I am using an R markdown file as my lab book as it will allow me to store my code, figures and notes all in one place. I will outline the steps of my analysis before I perform it and note down any observations. When I am done I will convert this to a word document using the knit to word function for submission.
I’ve separated the document into headings which give the dates that I did each part of the analysis.
Clear the global environment
I’ve included this becuase my code wasnt working and this command fixed it.It could be that a previous operation is confliting with what I was trying to do, runnning this console command resets all variables, allowing you to run the whole thing again from fresh without having to restart R studio. Ive left it at the top for convenience.
rm(list = ls())
16/10/2020 Preprocessing of the count data
I retrieved the count data from my supervisor in the form of multiple csv files, each containing the raw count data for each sample and the ensembl ids of the genes. The filenames where as follows:
readspergene_cyp21_2.out.xlsx readspergene_cyp21_1.out.xlsx readspergene_cyp21_3.out.xlsx readspergene_cyp21HC_2.out.xlsx readspergene_cyp21HC_3.out.xlsx readspergene_cyp21HC_1.out.xlsx readspergene_WT_1.out.xlsx readspergene_WT_2.out.xlsx readspergene_WT_4.out.xlsx readspergene_WTHC_1.out.xlsx readspergene_WT_3.out.xlsx readspergene_WTHC_2.out.xlsx *readspergene_WTHC_3.out.xlsx
I copied and pasted the count data from each of these files into a new excel file which was named counts.xlsx. I then converted this file to .txt format so that it could be read into R as a table.
Finally I created a metadata file containing the genotype and treatment of each sample which I named metadata.txt. The data is now ready to be imported into R.
17/10/2020 Importing the Data into R
Today I am importing the data into R studio for analysis, and creating a dataset using deseq. I will use the readr package to read in the count data and metadata from the .txt files mentioned above. I have added the readr documnetation to my list above. The deseq package will then transform and combine this data into one single object, which saves a lot of time and effort. I stored the raw counts data in a data frame called counts and my metadata in a dataframe called sampleinfo. Once again i have added the deseq package documentation to my list above.
#Initialise the readr library
library(readr)
#Read in the count data
counts = read.table("Raw data/counts.txt", header = TRUE)
#Read in the metadata
sampleinfo = read.table("Raw data/metadata.txt", header = TRUE)
Creating the Deseq dataset
To allow for analysis my count data and metadata must be combined into a single object. This could be done using base R however the process would be very long and painful. Luckily there is an R package offered by bioconductor that allows for the analysis of RNAseq data quickly. This package is known as DEseq2, and can be used to combine my data into a single object, containing the count data and sample information from the study.
The DESeqDataSetFromMatrix() function takes the count matrix (the count data table) and the metadata (information about each sample) and combines them into one dataset. The design is set to the experimental design of the study, ie what condition we are comparing between samples. I set it to genotype as i wish to compare the mutant and wild type samples first.
In order to check that my sample information had been assigned correctly i used the colData function to check that each sample had the correct treatment and genotype assigned to them.
#Initialise the deseq2 package
library(DESeq2)
Loading required package: S4Vectors
Loading required package: stats4
Loading required package: BiocGenerics
Loading required package: parallel
Attaching package: ‘BiocGenerics’
The following objects are masked from ‘package:parallel’:
clusterApply, clusterApplyLB, clusterCall, clusterEvalQ, clusterExport, clusterMap, parApply,
parCapply, parLapply, parLapplyLB, parRapply, parSapply, parSapplyLB
The following objects are masked from ‘package:stats’:
IQR, mad, sd, var, xtabs
The following objects are masked from ‘package:base’:
anyDuplicated, append, as.data.frame, basename, cbind, colnames, dirname, do.call, duplicated,
eval, evalq, Filter, Find, get, grep, grepl, intersect, is.unsorted, lapply, Map, mapply,
match, mget, order, paste, pmax, pmax.int, pmin, pmin.int, Position, rank, rbind, Reduce,
rownames, sapply, setdiff, sort, table, tapply, union, unique, unsplit, which, which.max,
which.min
Attaching package: ‘S4Vectors’
The following object is masked from ‘package:base’:
expand.grid
Loading required package: IRanges
Loading required package: GenomicRanges
Loading required package: GenomeInfoDb
Loading required package: SummarizedExperiment
Loading required package: Biobase
Welcome to Bioconductor
Vignettes contain introductory material; view with 'browseVignettes()'. To cite Bioconductor,
see 'citation("Biobase")', and for packages 'citation("pkgname")'.
Loading required package: DelayedArray
Loading required package: matrixStats
Attaching package: ‘matrixStats’
The following objects are masked from ‘package:Biobase’:
anyMissing, rowMedians
Attaching package: ‘DelayedArray’
The following objects are masked from ‘package:matrixStats’:
colMaxs, colMins, colRanges, rowMaxs, rowMins, rowRanges
The following objects are masked from ‘package:base’:
aperm, apply, rowsum
#Combine metadata and count data into single dds object
dds <- DESeqDataSetFromMatrix(countData = counts,colData = sampleinfo, design = ~Genotype)
some variables in design formula are characters, converting to factors
#Checking that metadata has been correctly assigned
colData(dds)
DataFrame with 13 rows and 2 columns
Genotype Treatment
<factor> <character>
WT1 WT untreated
WT2 WT untreated
WT3 WT untreated
WT4 WT untreated
cyp21_MUT1 MUT untreated
... ... ...
cyp21_MUT.HC2 MUT treated
cyp21_MUT.HC3 MUT treated
WT.HC1 WT treated
WT.HC2 WT treated
WT.HC3 WT treated
After inspecting the colData property of the dds object it is apparent that the sample id column did not have a name. This is due to the fact that deseq automatically imports the sample names from the csv file as rownames in the deseq dataset. This may make analysis difficult if I wish to select samples based on their name, so I wrote a code block that creates a sample id column, with all the sample ids and adds this to the deseq dataset.This uses the cbind function which allows you to create a new column and assign values to the subsequent rows. I learned how to do this through reading the R documentation for cbind(): https://www.rdocumentation.org/packages/base/versions/3.6.2/topics/cbind
#Create a new column in the colData item corrosponding to the rownames
colData(dds) <- cbind(Name = rownames(colData(dds)), colData(dds))
#Inspect results
colData(dds)
DataFrame with 13 rows and 3 columns
Name Genotype Treatment
<character> <factor> <character>
1 WT1 WT untreated
2 WT2 WT untreated
3 WT3 WT untreated
4 WT4 WT untreated
5 cyp21_MUT1 MUT untreated
... ... ... ...
9 cyp21_MUT.HC2 MUT treated
10 cyp21_MUT.HC3 MUT treated
11 WT.HC1 WT treated
12 WT.HC2 WT treated
13 WT.HC3 WT treated
The rownames are now numbers which I cant get rid of however I will be able to use the Name column to select samples, therefor the row numbers are irrelevant and shouldnt interfere with any analysis (this remains to be seen).
Future research has revealed that I could’ve just used the rownames() function to select the samples however I prefer to have them in a named column as it makes the data easier to read in my opinion.
21/10/2020 Quality analysis of the data
In order to check that samples are labelled correctly and that the count data follows a normal distribution I must first conduct quality analysis of the count data.
In order to visualise the distribution of count data it must first be transformed to account for large differences in counts that might skew the data. deseq2 has two inbuilt functions to do this: rlog() and vst(). Both of these do essentially the same thing; they both conduct a log2 transformation on the data. I’ve seen a lot of people in online threads saying that vst is better and faster for large datasets, so i will use that.
#Transform the data
vsd = vst(dds, blind = TRUE)
Boxplot of normalised count data
I used a boxplot to assess the distribution of the transformed count data. The blue line represents where the medians pf each sample lines up. Initially the sample labels on the x axis were cut off so I had to resize the figure to compensate for this. This blog proved a very useful resource when learning how to do this: http://zevross.com/blog/2017/06/19/tips-and-tricks-for-working-with-images-and-figures-in-r-markdown-documents/
par(cex.axis=0.6)
boxplot(assay(vsd), ylab="Log2 counts",las=2,main="Normalised Distributions", names = vsd$Name)
# Added a blue horizontal line that corresponds to the median logCPM
abline(h=median(assay(vsd)), col="blue")

The medians of all the data appear to line up aside from some slight variability in the mutant treated samples, two of which show medians slightly above the line. as a result I can conclude that these data have been normalized successfully.
Since my data is normalised I can conduct the other quality analysis tomorrow.
22/10/2020 Principle componant analysis
In order to visualise the relative similarity of samples I can use a PCA plot. This compares samples based on their two principle components, and plots their similarity on a two dimensional grid, relative to all other samples in the study. Samples that are similar will likely form clusters together within a quadrant of the graph. IN a perfect world we should expect significant overlap between results of the same group however there is likely to be some biological variability that impacts this. As long as there’s no distinct crossover between groups then I can conclude the samples are correctly labelled.
In order to create the plot I am using two packages: deseq2 and ggplot. deseq2 has a function dedicated to making pca plots of genetic data, which i will use to make the plot itself. I can then use ggplot to modify this graph and make modifications to make it easier to visualise the data.
My supervisor taught me how to make a pca plot for one of my comparisons, however after looking at the documentation from deseq2 it appears that I can define an interest group as a vector that covers all sample conditions defined in the colData (metadata). My pca plot will therefor be one plot that covers all samples in the study.
I generated the plot with the interest groups being treatment and genotype in order to gain an overview of how each group of samples was different. I limited the X and Y scales after experimenting to see which settings gave the best sized graph where all the data was visible. I used the figure.heading and figure.height parameters in the chunk options to resize the graph to a suitable size ensuring visibility.
gglpot was used to turn each data into a sample label.
#Initialise the ggplot2 library
library(ggplot2)
#Create the pca plot, intgroup is a vector with genotype and treatment
plot = plotPCA(vsd, intgroup = c("Genotype","Treatment"))
#print the plot with sample information and scale modifications using ggplot2
plot + geom_label(aes(label = vsd$Name)) + coord_fixed(xlim = c(-30,30), ylim = c(-20,20))
Coordinate system already present. Adding new coordinate system, which will replace the existing one.

The PCA plot shows distinct sample clustering based on genotype and treatment group. It appears the wildtype treated and mutant treated samples are more similar to each other than their non treated counterparts. There appears to be most variation within the mutant treated group, with CYP_MUT.HC1 being seperated from the other two samples. These small differences are likely due to biological variability within the samples and are unlikely to effect results.
cluster dendorograms are another method of assessing similarity. These provide a tree with branches connecting samples that are related i.e more similar. Hopefully the samples will branch based on their genotype and treatment group, indicating differences in gene expression between these factors.
Sample clustering analysis
#PLot Dendogram
plot(hclust(dist(t(assay(vsd)))), labels = vsd$Name)

The cluster dendogram shows that there is a large amount of similarity within groups apart from the mutant treated samples where CYP_MUT.HC3 is shown to be slightly more similar to the wild type treated samples.
Cluster heatmap
In order to get a more quantitative overview of sample similarity a heatmap can be generated from the correlations in the count data. In order to do this I used the pheatmap library which allows for generation of heatmaps. The heatmap will compare each sample to one another, with the degree of redness of each tile showing sample simlarity. I should expect to see deep red where samples of the same group are compared and deep blue where samples of differing groups are compared. As a result the heatmap should display clusters of red and blue. I used the metadata mentioned earlier to annotate the columns and rows of the heatmap based on the genotype an treatment of each sample.
#Initialise the pheatmap library
library(pheatmap)
#Retrieve the metadata for annotation
sampleinfo = as.data.frame(colData(dds)[,c('Treatment','Genotype')])
#Retrieve normalised count data
assay = assay(vsd)
#Calculate correlations
assay_cor <- cor(assay)
# 1. Open jpeg file
png("Figures/qa heatamp", width = 700)
# 2. Create the plot
#Plot correlations on annotated heatmap
pheatmap(assay_cor,
annotation = sampleinfo,
annotation_row = sampleinfo,
labels_row = vsd$Name,
labels_col = vsd$Name)
# 3. Close the file
dev.off()
null device
1
The heatmap shows clustering where similar groups are compared. It appears there is a large amount of similarity between wild type and mutant treated samples, and a greater difference between the two genotypes when untreated. There also appears to be a large amount of variability within the mutant untreated group, which indicates biological differences in gene expression between the samples.
27/10/2020 Differential expression analysis: experimental design
The aims of the study are to identify cyp21a2 dependant glucocorticoid regulated gened and to assess the effects of hydrocortsione on the mutant phenotype. In order to assess this I will make multiple pair wise gene expression comparisions:
WT V MUT to analyse the success of mutation and its effect on gene transcription
MUT treated V MUT untreated to assess the effects of the treatment
WT V MUT treated to assess how different the treated mutants are from the norm
WT treated V WT untreated to assess the efffects of elevated glucocorticoid signalling on gene transcription
I then aim on visualising this data with methods such as heatmaps and volcano plots.
4 comparisons may be too many to talk about in my final report and if that’s the case then i will pick out the most interesting ones.
In order to analyse this data i will need to make subsets of the dds object i created earlier corrsponding to each of the comparisons that i wish to make. Once i have figured out how to do this i can conduct my analysis and visualise the data
###Subsetting the deseq dataset After reading through the documentation for the deseq2 package It seems i can subset the data by gnerating different datasets corrosponding to each pairwise analysis from my original dds object. It is a simple case of retrieving the counts for each sample in the group that i wish to comapre and creating a new deseqdataset containing just that information. Once i have this I can run the deseq() function which will transform and analyse my data, calculating the foldchange in gene expression and assigning statistical significance.
If i cant get the subsetting to work an alternative method would be to maunally copy and paste the pairwise data into individual csv files, and then read that data into R seperately, which was recommended by dr cunliffe. However I wish to try subsetting the data in R first as it will ensure that no human error occured through munual copying and pasting of the data. If i cant get this to work then i will manually copy and paste the data into excel files.
WT untreated vs mutant untreated
The following should successfully create my first subset (WT V MUT)
#Retrieve counts for untreated samples
dds_genotype = dds[,which(dds$Treatment == "untreated")]
#Set the design to compare expression between genotypes
design(dds_genotype) = ~Genotype
#Use DESeq2 to analyse data
de_genotype = DESeq(dds_genotype)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
#Generate results, using MUT as baseline for log fold change
genotype_results = results(de_genotype, c('Genotype','MUT','WT'))
Tge deseq function calculates log fold change in gene expression. in this case since i set the comparison to mutant vs wt it will calculate the change in mutant to wild type. A positive fold change indicates a greater expression in the mutant, wilst a negative fold change indicates decreased expression. Deseq also calculates the adjusted p value, which gives indication of statistical significance. The lower this is the more significant the result.
Since this successfully subsetted the data, and i now have an object corresponding to just the mutant and wildtype untreated samples, I will now create subsets for the rest of the data.
Mutant treated vs mutant untreated
When changing the design to compare between treatment groups i came accross a problem. When deseq read in the sample info it assigned the treatment column to be a character vector as opposed to a factor. In order to use the Treatment as a design I need to convert it to a factor which I can do using the as.factor() function which i learned how to use here: https://www.rdocumentation.org/packages/h2o/versions/2.4.3.11/topics/as.factor
#Convert the Treatment character vector to factor
dds$Treatment = as.factor(dds$Treatment)
I can now subset the data, this time using Treatment as the design.
#Retrieve counts for mutant samples
dds_muttreatment = dds[,which(dds$Genotype == "MUT")]
#Set the design to compare expression between treatments
design(dds_muttreatment) = ~Treatment
#Use DESeq2 to analyse data
de_muttreatment = DESeq(dds_muttreatment)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
#Store results
mutreatment_results = results(de_muttreatment, contrast = c('Treatment','treated','untreated'))
Mutant treated vs WT
Subsetting this data is a bit more tricky. My which() function needs logic to determine which samples are both mutant and treated and samples that are WT and untreated. In order to do this I created two vectors, one selecting mutant treated samples and one containing WT untreated samples. This was done using the and (&) and or (|) logical operators.
#Retrieve counts for mutant treated and wildtype untreated samples
dds_mutreatedwt = dds[,which(c(dds$Genotype == "MUT" & dds$Treatment == 'treated') | c(dds$Genotype == 'WT' & dds$Treatment == 'untreated'))]
#Set the design to compare expression between treatments
design(dds_mutreatedwt) = ~Treatment
#Use DESeq2 to analyse data
de_mutreatedwt = DESeq(dds_mutreatedwt)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
#Store results
muttreatedwt_results = results(de_mutreatedwt, c('Treatment','treated','untreated'))
WT treated vs WT unntreated
This is just a simple case of seperating the WT data into a subset as i did before with the mutant samples
#Retrieve counts for mutant samples
dds_wt = dds[,which(dds$Genotype == "WT")]
#Set the design to compare expression between treatments
design(dds_wt) = ~Treatment
#Use DESeq2 to analyse data
de_wt = DESeq(dds_wt)
estimating size factors
estimating dispersions
gene-wise dispersion estimates
mean-dispersion relationship
final dispersion estimates
fitting model and testing
#Store results
wt_results = results(de_wt, contrast = c('Treatment','treated','untreated'))
Now that I’ve subsetted the data i can move on to visualisation, which i will do another day.
28/10/2020 Processing results for visualisation
Now that ive generated my results theres a few things I need to do before graphing them. First I need to assign external gene names to my results to make differentailly expressed genes easily identifiable by their name as opposed to a long ensembl id, which makes it easier to label them (and google them).
In order to add gene symbols I need a database containting gene symbols matched to ensembl ids. For this i used the biomart package, which is a library of all gene names matched to ensembl id for many different organsims. The gene symbols will need to be matched to the ensembl ids in my results and joined to each results table.
First i will retrieve the gene symbols from biomaRt:
#Initialise database with gene symbols
library(biomaRt)
#retrieve data for zebrafish
ensembl = useMart("ensembl",dataset="drerio_gene_ensembl")
Each of my results objects does not contain a column for ensembl id. instead the ensembl id of each gene is a row name. This is a problem as i wont be able to easily select the ensembl ids of each gene to match with those in the external database. I will have to therefor assign a new column to each of my results tables containing the ensembl ids of the genes. I did this using the sapply function to create a new column named “ensembl” that contained the rownames of the table and therefor the ensembl ids of each gene.
#Create new columns for ensmbl id in each results table
genotype_results$ensembl <- sapply( strsplit( rownames(genotype_results), split="\\+" ), "[", 1 )
mutreatment_results$ensembl <- sapply( strsplit( rownames(mutreatment_results), split="\\+" ), "[", 1 )
muttreatedwt_results$ensembl <- sapply( strsplit( rownames(muttreatedwt_results), split="\\+" ), "[", 1 )
wt_results$ensembl <- sapply( strsplit( rownames(wt_results), split="\\+" ), "[", 1 )
All the gene symbols and ensembl ids are stored in the ensembl object. In order to match these to my results I need to create a genemap object that retrieves the ensembl id and external gene names that match with the ensembl ids in my results. since all subsets tested for the same genes i can use any of them to match the emsmbl ids and create the gene map.
#Generate genemap with ensembl ids and external gene names.
genemap = getBM (attributes = c("ensembl_gene_id","external_gene_name"),
filters = "ensembl_gene_id",
values = wt_results$ensembl,
mart = ensembl)
The genemap object now contains a table with the ensembl id from my results and the corrosponding external gene id from the bioMart database. I now need to join this to my original results tables individually.
#Match gene symbols with ensembl ids from results
idx = match(wt_results$ensembl, genemap$ensembl_gene_id)
#Join the gene id table to each of my results tables
wt_results$external_gene_name = genemap$external_gene_name[idx]
genotype_results$external_gene_name = genemap$external_gene_name[idx]
mutreatment_results$external_gene_name = genemap$external_gene_name[idx]
muttreatedwt_results$external_gene_name = genemap$external_gene_name[idx]
Now that I have my results for each pairwise comparison I can save them to csv files to store the data and make sure I dont have to run all of the above code again in the future. Instead i can simply read the data from these files whenever i need it. Furthermore it means i have a permanant copy of my results, reducing the chances of me losing them.
In order to convert the data to a csv file i can use the readr write.csv() function. My data has to be in the form of a data frame in order to do this so I converted it using as.data.frame(). I also arranged the data by padj in order to see which results where the most significant.
The directories used to store the results can be seen in the code below.
library(dplyr)
Attaching package: ‘dplyr’
The following object is masked from ‘package:matrixStats’:
count
The following object is masked from ‘package:Biobase’:
combine
The following objects are masked from ‘package:GenomicRanges’:
intersect, setdiff, union
The following object is masked from ‘package:GenomeInfoDb’:
intersect
The following objects are masked from ‘package:IRanges’:
collapse, desc, intersect, setdiff, slice, union
The following objects are masked from ‘package:S4Vectors’:
first, intersect, rename, setdiff, setequal, union
The following objects are masked from ‘package:BiocGenerics’:
combine, intersect, setdiff, union
The following object is masked from ‘package:biomaRt’:
select
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
#Write wt results to a file
write.csv(arrange(as.data.frame(wt_results), padj),file = "Results/wt_results.csv")
#Write genotype results to a file
write.csv(arrange(as.data.frame(genotype_results), padj),file = "Results/genotype_results.csv")
#Write the mutated treatment results to a file
write.csv(arrange(as.data.frame(mutreatment_results), padj),file = "Results/Mutant_treatment_results.csv")
#Write the mutant treated vs wt results to a file
write.csv(arrange(as.data.frame(muttreatedwt_results), padj),file = "Results/Mutant_treated_vs_wt_results.csv")
29/10/2020 Visualising the data
Now i need to visualise the data for each of my pairwise analysis
29/10/2020 Mutant untreated vs wildtype untreated samples
First i need to shrink the log fold changes of my results in order to properly visualizes the data without any extreme values interfering. In order to do this i will use the deseq2 lfcshrink function.
#Shrink the log fold changes
shrink_genotype = lfcShrink(de_genotype, contrast = c('Genotype','MUT','WT'), res = genotype_results, type = 'normal')
using 'normal' for LFC shrinkage, the Normal prior from Love et al (2014).
Note that type='apeglm' and type='ashr' have shown to have less bias than type='normal'.
See ?lfcShrink for more details on shrinkage type, and the DESeq2 vignette.
Reference: https://doi.org/10.1093/bioinformatics/bty895
In order to gain an overview of my data i can generate an ma plot. This gives an overview of the distrvution of my data, i.e whether there is more overall upregulation or downregulation of genes.
Ma plot of mutant vs wildtype
sig_genotype = subset(genotype_results, padj < 0.05)
plotMA(sig_genotype,ylim = c(-10,10))

The Ma plot gives me an overview of the differential expression. the ma plot shows that more genes where Downregulated in the wildtype compared to the mutants
Next I created a volcano plot which plots the log fold change against the p value of each gene. Genes with a pvalue of less than 0.05 and a fold change greater than +1 or -1 are highlighhted in red. I set the code to label the top 30 most significant genes where possible, however some of the datapoints are so close that a distinct label cannot be applied. Once again i resized the figure using the chunk settings.
Volcano plot of mutant vs wildtype
shrink_genotype = arrange(as.data.frame(shrink_genotype),padj)
symb = shrink_genotype$external_gene_name[1:30]
library(EnhancedVolcano)
Loading required package: ggrepel
EnhancedVolcano(shrink_genotype,
lab = shrink_genotype$external_gene_name,
selectLab = c(symb),
labSize = 9.0,
pointSize = 7.0,
title = "CYP21A2 MUT vs WT",
axisLabSize = 35,
titleLabSize = 50,
subtitle = " ",
x ='log2FoldChange',
y ='padj',
legendLabels=c('Not sig.','Log (base 2) FC','p-value',
'p-value & Log (base 2) FC'),
legendPosition = 'right',
legendLabSize = 20,
legendIconSize = 10)

The plot shows that more genes where downregulated in the mutant compared to upregulated. The gene fkbp5 is clearly the most downregulated gene and shows the highest statistical significance. Paics was the most significant upregulated gene in the mutants.
I can also create a heatmap based on the read data for each gene in order to give a closer look at the differences between expression. I created a matrix containing the top 30 most significantly expressed genes which I then created the heatmap from. I used the sampleinfo object to label the genotypes of the samples and annotated each row with the gene symbols.
I used the symb variable from earlier to label each row with the gene id.
#Initialise pheatmap if not done previously
library(pheatmap)
#log2 transformation
vsd_genotype = vst(dds_genotype)
#Create matrix containing the top 30 most significant genes
genotype_mat = assay(vsd_genotype)[ head(order(genotype_results$padj),30), ]
#Subtract the mean reads for each gene
genotype_mat = genotype_mat - rowMeans(genotype_mat)
#Read in genotypes for annotation
sampleinfo = as.data.frame(colData(dds)[c('Genotype')])
#Plot heatmap
pheatmap(genotype_mat,
fontsize = 7,
cellwidth = 30,
cellheight = 7,
labels_row = symb,
annotation = sampleinfo,
cluster_rows = F,
clustering_distance_rows = F,
labels_col = dds_genotype$Name)

The heatmap provides more insight into the results behind the volcano plot. It shows a significant difference between reads for fkbp5 in the WT and Mut samples. Of the top 30 genes only 4 where upregulated in the mutants, the rest all show quite s significant downregulation.
Now that I have a basic set of graphs i can repeat this process for the other comparisons.
01/11/2020 Mutant treated vs untreated
Ma plot of mutant treated vs untreated
The Ma plot shows treated vs untreated mutant samples. those with a negative fold change are underexpressed in the treated group and those with a positive fold change where upregulted in the treated group. The plot shows that more genes where upregulated than downregulated in the treated group.
#Subset top 30 most sig results
sig_muttreatment = subset(mutreatment_results, padj < 0.05)
#create plot
plotMA(sig_muttreatment, ylim = c(-10, 10))

Next i produced a volano plot. As before i performed an lfc shrink on the data
#Shrink lfc
shrink_muttreatment = lfcShrink(de_muttreatment, contrast = c('Treatment','treated','untreated'), res = mutreatment_results, type = 'normal')
using 'normal' for LFC shrinkage, the Normal prior from Love et al (2014).
Note that type='apeglm' and type='ashr' have shown to have less bias than type='normal'.
See ?lfcShrink for more details on shrinkage type, and the DESeq2 vignette.
Reference: https://doi.org/10.1093/bioinformatics/bty895
I created the volcano plot as previously described, except this time using the muttreatment dataset.
#Arrange by p value
shrink_muttreatment = arrange(as.data.frame(shrink_muttreatment),padj)
#Retrieve symbols of top 30 genes
symb = shrink_muttreatment$external_gene_name[1:30]
library(EnhancedVolcano)
#Create plot
EnhancedVolcano(shrink_muttreatment,
lab = shrink_muttreatment$external_gene_name,
labSize = 7.0,
selectLab = c(symb),
pointSize = 5.0,
title = "CYP21A2 MUT treated vs untreated",
axisLabSize = 35,
titleLabSize = 50,
subtitle = " ",
x ='log2FoldChange',
y ='padj',
legendLabels=c('Not sig.','Log (base 2) FC','p-value',
'p-value & Log (base 2) FC'),
legendPosition = 'right',
legendLabSize = 20,
legendIconSize = 10)

Interestingly the plot shows an almost complete reversal in gene expression. most noticabile is the change in fkbp5 which is singicantly upregulated in the treated group.
I then created a heatmap as described before
#Initialise pheatmap if not done previously
library(pheatmap)
#log2 transformation
vsd_muttreated = vst(dds_muttreatment)
#Create matrix containing the top 30 most significant genes
muttreated_mat = assay(vsd_muttreated)[ head(order(mutreatment_results$padj),30), ]
#Subtract the mean reads for each gene
muttreated_mat = muttreated_mat - rowMeans(muttreated_mat)
#Read in genotypes for annotation
sampleinfo = as.data.frame(colData(dds_muttreatment)['Treatment'])
#Plot heatmap
pheatmap(muttreated_mat,
fontsize = 7,
cellwidth = 30,
cellheight = 7,
labels_row = symb,
annotation = sampleinfo,
cluster_rows = F,
clustering_distance_rows = F,
labels_col = dds_muttreatment$Name)

Once again it appears that the expression is the opposite when the mutants are treated. Only one gene was downregulated, whilst all the reat inlcuding fkbp5 where significantly upregulated
#01/11/2020 Mutant treated vs wild type ### Ma plot of mutant treated vs WT untreated
sig_muttreatmentwt = subset(muttreatedwt_results, padj < 0.05)
plotMA(sig_muttreatmentwt, ylim = c(-10, 10))

Interestingly this MA plot shows the greatest difference in expression so far. There are more significant genes on this plot than in the previous two comparisons, despite the fact that I ecprected the treated mutants to have at least some similarity to the wild types.
Next i produced a volano plot. As before i performed an lfc shrink on the data
shrink_muttreatmentwt = lfcShrink(de_mutreatedwt, contrast = c('Treatment','treated','untreated'), res = muttreatedwt_results, type = 'normal')
using 'normal' for LFC shrinkage, the Normal prior from Love et al (2014).
Note that type='apeglm' and type='ashr' have shown to have less bias than type='normal'.
See ?lfcShrink for more details on shrinkage type, and the DESeq2 vignette.
Reference: https://doi.org/10.1093/bioinformatics/bty895
I created the volcano plot as previously described, except this time using the muttreatmentwt dataset.
shrink_muttreatmentwt = arrange(as.data.frame(shrink_muttreatmentwt),padj)
symb = shrink_muttreatmentwt$external_gene_name[1:30]
library(EnhancedVolcano)
EnhancedVolcano(shrink_muttreatmentwt,
lab = shrink_muttreatmentwt$external_gene_name,
selectLab = c(symb),
labSize = 9.0,
pointSize = 5.0,
title = "CYP21A2 MUT treated vs WT untreated",
axisLabSize = 35,
titleLabSize = 50,
subtitle = " ",
x ='log2FoldChange',
y ='padj',
legendLabels=c('Not sig.','Log (base 2) FC','p-value',
'p-value & Log (base 2) FC'),
legendPosition = 'right',
legendLabSize = 20,
legendIconSize = 10)

Once again this plot shows that there is a signifcant difference between the gene expression, however unlike the previous two comparisons it isnt skewed in any direction. Significanlty downregulated genes include some involved in immune regulation, such as anxa1.
I then created a heatmap as described before
#Initialise pheatmap if not done previously
library(pheatmap)
#log2 transformation
vsd_mutreatedwt = vst(dds_mutreatedwt)
#Create matrix containing the top 30 most significant genes
muttreatedwt_mat = assay(vsd_mutreatedwt)[ head(order(muttreatedwt_results$padj),30), ]
#Subtract the mean reads for each gene
muttreatedwt_mat = muttreatedwt_mat - rowMeans(muttreatedwt_mat)
#Read in genotypes for annotation
sampleinfo = as.data.frame(colData(dds_mutreatedwt)[c('Genotype','Treatment')])
#Plot heatmap
pheatmap(muttreatedwt_mat,
fontsize = 7,
cellwidth = 30,
cellheight = 7,
labels_row = symb,
annotation = sampleinfo,
cluster_rows = F,
clustering_distance_rows = F,
labels_col = dds_mutreatedwt$Name)

The heatmap mirrors what was seen in the volcano plot, however when comparing this with the others it appears that the difference in the count data is not as pronounced as it was in the previous two comparisons. This may indicate a lower amount of overall difference, implying that although there are differences, these are less prpnounced and may have less of an effect.
#03/11/2020 Wild type treated vs wild type untreated
Ma plot of wild type treated vs untreated
The Ma plot shows even more difference in this case. It appears that elevated glucocorticoid signalling has a significant effect on gene expression.
#Filter sig genes
sig_wt = subset(wt_results, padj < 0.05)
#PLot data
plotMA(sig_wt, ylim = c(-10, 10))

Next i produced a volano plot. As before i performed an lfc shrink on the data
#lfc shrink
shrink_wt = lfcShrink(de_wt, contrast = c('Treatment','treated','untreated'), res = wt_results, type = 'normal')
using 'normal' for LFC shrinkage, the Normal prior from Love et al (2014).
Note that type='apeglm' and type='ashr' have shown to have less bias than type='normal'.
See ?lfcShrink for more details on shrinkage type, and the DESeq2 vignette.
Reference: https://doi.org/10.1093/bioinformatics/bty895
I created the volcano plot as previously described, except this time using the muttreatment dataset.
#arrange by p value
shrink_wt = arrange(as.data.frame(shrink_wt),padj)
#Collect top 30 gene symbols
symb = shrink_wt$external_gene_name[1:30]
library(EnhancedVolcano)
#Produce plot
EnhancedVolcano(shrink_wt,
lab = shrink_wt$external_gene_name,
selectLab = c(symb),
labSize = 7.0,
pointSize = 5.0,
title = "WT treated vs untreated",
axisLabSize = 35,
titleLabSize = 50,
subtitle = " ",
x ='log2FoldChange',
y ='padj',
legendLabels=c('Not sig.','Log (base 2) FC','p-value',
'p-value & Log (base 2) FC'),
legendPosition = 'right',
legendLabSize = 20,
legendIconSize = 10)

Slightly more genes where downrefulated in the treated group compared to the untreated. Once again these genes appear to be involved in immune response with annexin making an appearance again. As before hsbp6 was also upregulated. This may indicate that treatment with hydrocortisone producing effects on gene expression that are associated with elevated glucocorticoid signalling. Is the treatment therefor an overkill?
I then created a heatmap as described bef
#Initialise pheatmap if not done previously
library(pheatmap)
#log2 transformation
vsd_wt = vst(dds_wt)
#Create matrix containing the top 30 most significant genes
wt_mat = assay(vsd_wt)[ head(order(wt_results$padj),30), ]
#Subtract the mean reads for each gene
wt_mat = wt_mat - rowMeans(wt_mat)
#Read in genotypes for annotation
sampleinfo = as.data.frame(colData(dds_wt)['Treatment'])
#Plot heatmap
pheatmap(wt_mat,
fontsize = 7,
cellwidth = 30,
cellheight = 7,
labels_row = symb,
annotation = sampleinfo,
cluster_rows = F,
clustering_distance_rows = F,
labels_col = dds_wt$Name)

The heatmap shows significant upregulation in the top 30 genes. genes of note are once again the annexin genes, whic are involved in immune response.
#05/11/2020 Comparing De gene lists Inorder to follow up on the idea that the treatment produced similar effects on the mutants as it did in the wild type im going to compare the differentially expressed genes in both groups. I can use the limma library to make a venn diagram showing overlap between the significantly differentially expressed genes
#Create a data frame with two lists of differentially expressed genes to compare
venn_data = data.frame(Mutant_treated_vs_wt = muttreatedwt_results$padj<0.05, WT_vs_WT_treated = wt_results$padj < 0.05, MUT_treated_vs_untreated = mutreatment_results$padj < 0.05)
#initialise the limmma library for producing the venn diagram
library(limma)
Attaching package: ‘limma’
The following object is masked from ‘package:DESeq2’:
plotMA
The following object is masked from ‘package:BiocGenerics’:
plotMA
#Plot data
vennDiagram(venn_data)

There appears to be signifcant overlap between the de gene lists, which may indicate that the treatment produces similar affects to those seen under elevated glucocorticoid signalling.
#09/11/2020 Gene enrichment analysis In order to assess the biological significance of these results we need to figure out the biological processes that these genes are involved in. This will involve gene ontology analysis. Over time genes have been assigned to certain GO terms (gene ontology). for example a gene involved in amino acid catabolism will have that as its GO term. Multiple genes are assigned to the same GO terms, and genes can have lots of different GO terms.
In order to assign the GO terms and visualise the resulting data i will be using two online resources: GOrilla and revigo. GOrilla allows the user to paste in a single list of genes ranked by adjusted p value, from most significant to least. It will then assing GO terms to these genes, taking into account the organism that they belong to and the significance of their appeartance in the list. A list of GO terms is produced relating to biological processes, functions or locations depending on what the suer wishes to view.
The list of GO terms can then be fed into revigo, which is an online tool allowing for the visualisation of this list. It takes into account the significance of each GO term and allows for the production of a treemap showing eah term in different sized boxes depending on how sognificantly they appear.
To produce each list i will use the csv files i created earlier. The data is already ordered by adjusted p value, so therefor i just need to paste the external_gene_name columns into GOrilla to generate the list. The resulting list of GO terms will then be fed into an R script generated by revigo to produce the treemaps
I generated four treemaps in the form of pdf files:
- MUTVWT.pdf
- MUTtreatVMUT.pdf
- MUTtreatVWT.pdf
- WTtreatVWT.pdf
My analysis is finished. If have more time or need more results i will insert all upregulated genes and all dowregulated genes into GOrilla seperately in order to identify GO terms related to them specifically, however i already have a lot of results so this may be too much
LS0tCnRpdGxlOiAiQk1TMzk3IExhYiBib29rIgpvdXRwdXQ6CiAgd29yZF9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKZWRpdG9yX29wdGlvbnM6IG51bGwKY2h1bmtfb3V0cHV0X3R5cGU6IGlubGluZQotLS0KCkkgYW0gdXNpbmcgYW4gUiBtYXJrZG93biBmaWxlIGFzIG15IGxhYiBib29rIGFzIGl0IHdpbGwgYWxsb3cgbWUgdG8gc3RvcmUgbXkgY29kZSwgZmlndXJlcyBhbmQgbm90ZXMgYWxsIGluIG9uZSBwbGFjZS4gSSB3aWxsIG91dGxpbmUgdGhlIHN0ZXBzIG9mIG15IGFuYWx5c2lzIGJlZm9yZSBJIHBlcmZvcm0gaXQgYW5kIG5vdGUgZG93biBhbnkgb2JzZXJ2YXRpb25zLiBXaGVuIEkgYW0gZG9uZSBJIHdpbGwgY29udmVydCB0aGlzIHRvIGEgd29yZCBkb2N1bWVudCB1c2luZyB0aGUga25pdCB0byB3b3JkIGZ1bmN0aW9uIGZvciBzdWJtaXNzaW9uLgoKSSd2ZSBzZXBhcmF0ZWQgdGhlIGRvY3VtZW50IGludG8gaGVhZGluZ3Mgd2hpY2ggZ2l2ZSB0aGUgZGF0ZXMgdGhhdCBJIGRpZCBlYWNoIHBhcnQgb2YgdGhlIGFuYWx5c2lzLgoKIyMjIENsZWFyIHRoZSBnbG9iYWwgZW52aXJvbm1lbnQKSSd2ZSBpbmNsdWRlZCB0aGlzIGJlY3Vhc2UgbXkgY29kZSB3YXNudCB3b3JraW5nIGFuZCB0aGlzIGNvbW1hbmQgZml4ZWQgaXQuSXQgY291bGQgYmUgdGhhdCBhIHByZXZpb3VzIG9wZXJhdGlvbiBpcyBjb25mbGl0aW5nIHdpdGggd2hhdCBJIHdhcyB0cnlpbmcgdG8gZG8sIHJ1bm5uaW5nIHRoaXMgY29uc29sZSBjb21tYW5kIHJlc2V0cyBhbGwgdmFyaWFibGVzLCBhbGxvd2luZyB5b3UgdG8gcnVuIHRoZSB3aG9sZSB0aGluZyBhZ2FpbiBmcm9tIGZyZXNoIHdpdGhvdXQgaGF2aW5nIHRvIHJlc3RhcnQgUiBzdHVkaW8uIEl2ZSBsZWZ0IGl0IGF0IHRoZSB0b3AgZm9yIGNvbnZlbmllbmNlLgpgYGB7cn0Kcm0obGlzdCA9IGxzKCkpCmBgYAoKCiMgRG9jdW1lbnRhdGlvbiBmb3IgcGFja2FnZXMKVGhpcyBzZWN0aW9uIGlzIHVwZGF0ZWQgZXZlcnkgdGltZSBJIHVzZSBhIG5ldyBwYWNrYWdlLiBJdCB3aWxsIGluY2x1ZGUgYSBsaXN0IG9mIGxpbmtzIHRvIHVzZWZ1bCByZXNvdXJjZXMgb24gaG93IHRvIHVzZSBlYWNoIHBhY2thZ2UgaW4gY2FzZSBpIGNvbWUgYWNyb3NzIGFueSBwcm9ibGVtcyBpbiBteSBhbmFseXNpcwoK4oCiIHJlYWRyOiBodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvcmVhZHIvdmVyc2lvbnMvMS4zLjEK4oCiIERlc2VxMjogaHR0cHM6Ly93d3cuYmlvY29uZHVjdG9yLm9yZy9wYWNrYWdlcy9kZXZlbC9iaW9jL3ZpZ25ldHRlcy9ERVNlcTIvaW5zdC9kb2MvREVTZXEyLmh0bWwK4oCiIGdncGxvdDI6IGh0dHBzOi8vZ2dwbG90Mi50aWR5dmVyc2Uub3JnLyBOb3RlOiBub3QgdGVjaG5pY2FsbHkgZG9jdW1lbnRhdGlvbiBidXQgZG9lcyBjb250YWluIGEgdXNlZnVsIHNoZWF0IHNoZWV0CuKAoiBQaGVhdG1hcDogaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL3BoZWF0bWFwL3ZlcnNpb25zLzEuMC4xMi90b3BpY3MvcGhlYXRtYXAK4oCiIERwbHlyOiBodHRwczovL3d3dy5yZG9jdW1lbnRhdGlvbi5vcmcvcGFja2FnZXMvZHBseXIvdmVyc2lvbnMvMC43LjgKCgojIDE2LzEwLzIwMjAgUHJlcHJvY2Vzc2luZyBvZiB0aGUgY291bnQgZGF0YQpJIHJldHJpZXZlZCB0aGUgY291bnQgZGF0YSBmcm9tIG15IHN1cGVydmlzb3IgaW4gdGhlIGZvcm0gb2YgbXVsdGlwbGUgY3N2IGZpbGVzLCBlYWNoIGNvbnRhaW5pbmcgdGhlIHJhdyBjb3VudCBkYXRhIGZvciBlYWNoIHNhbXBsZSBhbmQgdGhlIGVuc2VtYmwgaWRzIG9mIHRoZSBnZW5lcy4gVGhlIGZpbGVuYW1lcyB3aGVyZSBhcyBmb2xsb3dzOgoKKnJlYWRzcGVyZ2VuZV9jeXAyMV8yLm91dC54bHN4CipyZWFkc3BlcmdlbmVfY3lwMjFfMS5vdXQueGxzeAoqcmVhZHNwZXJnZW5lX2N5cDIxXzMub3V0Lnhsc3gKKnJlYWRzcGVyZ2VuZV9jeXAyMUhDXzIub3V0Lnhsc3gKKnJlYWRzcGVyZ2VuZV9jeXAyMUhDXzMub3V0Lnhsc3gKKnJlYWRzcGVyZ2VuZV9jeXAyMUhDXzEub3V0Lnhsc3gKKnJlYWRzcGVyZ2VuZV9XVF8xLm91dC54bHN4CipyZWFkc3BlcmdlbmVfV1RfMi5vdXQueGxzeAoqcmVhZHNwZXJnZW5lX1dUXzQub3V0Lnhsc3gKKnJlYWRzcGVyZ2VuZV9XVEhDXzEub3V0Lnhsc3gKKnJlYWRzcGVyZ2VuZV9XVF8zLm91dC54bHN4CipyZWFkc3BlcmdlbmVfV1RIQ18yLm91dC54bHN4CipyZWFkc3BlcmdlbmVfV1RIQ18zLm91dC54bHN4CgpJIGNvcGllZCBhbmQgcGFzdGVkIHRoZSBjb3VudCBkYXRhIGZyb20gZWFjaCBvZiB0aGVzZSBmaWxlcyBpbnRvIGEgbmV3IGV4Y2VsIGZpbGUgd2hpY2ggd2FzIG5hbWVkIGNvdW50cy54bHN4LiBJIHRoZW4gY29udmVydGVkIHRoaXMgZmlsZSB0byAudHh0IGZvcm1hdCBzbyB0aGF0IGl0IGNvdWxkIGJlIHJlYWQgaW50byBSIGFzIGEgdGFibGUuCgpGaW5hbGx5IEkgY3JlYXRlZCBhIG1ldGFkYXRhIGZpbGUgY29udGFpbmluZyB0aGUgZ2Vub3R5cGUgYW5kIHRyZWF0bWVudCBvZiBlYWNoIHNhbXBsZSB3aGljaCBJIG5hbWVkIG1ldGFkYXRhLnR4dC4gVGhlIGRhdGEgaXMgbm93IHJlYWR5IHRvIGJlIGltcG9ydGVkIGludG8gUi4KCiMgMTcvMTAvMjAyMCBJbXBvcnRpbmcgdGhlIERhdGEgaW50byBSClRvZGF5IEkgYW0gaW1wb3J0aW5nIHRoZSBkYXRhIGludG8gUiBzdHVkaW8gZm9yIGFuYWx5c2lzLCBhbmQgY3JlYXRpbmcgYSBkYXRhc2V0IHVzaW5nIGRlc2VxLiBJIHdpbGwgdXNlIHRoZSByZWFkciBwYWNrYWdlIHRvIHJlYWQgaW4gdGhlIGNvdW50IGRhdGEgYW5kIG1ldGFkYXRhIGZyb20gdGhlIC50eHQgZmlsZXMgbWVudGlvbmVkIGFib3ZlLiBJIGhhdmUgYWRkZWQgdGhlIHJlYWRyIGRvY3VtbmV0YXRpb24gdG8gbXkgbGlzdCBhYm92ZS4gVGhlIGRlc2VxIHBhY2thZ2Ugd2lsbCB0aGVuIHRyYW5zZm9ybSBhbmQgY29tYmluZSB0aGlzIGRhdGEgaW50byBvbmUgc2luZ2xlIG9iamVjdCwgd2hpY2ggc2F2ZXMgYSBsb3Qgb2YgdGltZSBhbmQgZWZmb3J0LiBJIHN0b3JlZCB0aGUgcmF3IGNvdW50cyBkYXRhIGluIGEgZGF0YSBmcmFtZSBjYWxsZWQgY291bnRzIGFuZCBteSBtZXRhZGF0YSBpbiBhIGRhdGFmcmFtZSBjYWxsZWQgc2FtcGxlaW5mby4gT25jZSBhZ2FpbiBpIGhhdmUgYWRkZWQgdGhlIGRlc2VxIHBhY2thZ2UgZG9jdW1lbnRhdGlvbiB0byBteSBsaXN0IGFib3ZlLgoKYGBge3J9CiNJbml0aWFsaXNlIHRoZSByZWFkciBsaWJyYXJ5CmxpYnJhcnkocmVhZHIpCgojUmVhZCBpbiB0aGUgY291bnQgZGF0YSAKY291bnRzID0gcmVhZC50YWJsZSgiUmF3IGRhdGEvY291bnRzLnR4dCIsIGhlYWRlciA9IFRSVUUpCgoKI1JlYWQgaW4gdGhlIG1ldGFkYXRhCnNhbXBsZWluZm8gPSByZWFkLnRhYmxlKCJSYXcgZGF0YS9tZXRhZGF0YS50eHQiLCBoZWFkZXIgPSBUUlVFKQpgYGAKCiMjIyBDcmVhdGluZyB0aGUgRGVzZXEgZGF0YXNldApUbyBhbGxvdyBmb3IgYW5hbHlzaXMgbXkgY291bnQgZGF0YSBhbmQgbWV0YWRhdGEgbXVzdCBiZSBjb21iaW5lZCBpbnRvIGEgc2luZ2xlIG9iamVjdC4gVGhpcyBjb3VsZCBiZSBkb25lIHVzaW5nIGJhc2UgUiBob3dldmVyIHRoZSBwcm9jZXNzIHdvdWxkIGJlIHZlcnkgbG9uZyBhbmQgcGFpbmZ1bC4gTHVja2lseSB0aGVyZSBpcyBhbiBSIHBhY2thZ2Ugb2ZmZXJlZCBieSBiaW9jb25kdWN0b3IgdGhhdCBhbGxvd3MgZm9yIHRoZSBhbmFseXNpcyBvZiBSTkFzZXEgZGF0YSBxdWlja2x5LiBUaGlzIHBhY2thZ2UgaXMga25vd24gYXMgREVzZXEyLCBhbmQgY2FuIGJlIHVzZWQgdG8gY29tYmluZSBteSBkYXRhIGludG8gYSBzaW5nbGUgb2JqZWN0LCBjb250YWluaW5nIHRoZSBjb3VudCBkYXRhIGFuZCBzYW1wbGUgaW5mb3JtYXRpb24gZnJvbSB0aGUgc3R1ZHkuCgpUaGUgREVTZXFEYXRhU2V0RnJvbU1hdHJpeCgpIGZ1bmN0aW9uIHRha2VzIHRoZSBjb3VudCBtYXRyaXggKHRoZSBjb3VudCBkYXRhIHRhYmxlKSBhbmQgdGhlIG1ldGFkYXRhIChpbmZvcm1hdGlvbiBhYm91dCBlYWNoIHNhbXBsZSkgYW5kIGNvbWJpbmVzIHRoZW0gaW50byBvbmUgZGF0YXNldC4gVGhlIGRlc2lnbiBpcyBzZXQgdG8gdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24gb2YgdGhlIHN0dWR5LCBpZSB3aGF0IGNvbmRpdGlvbiB3ZSBhcmUgY29tcGFyaW5nIGJldHdlZW4gc2FtcGxlcy4gSSBzZXQgaXQgdG8gZ2Vub3R5cGUgYXMgaSB3aXNoIHRvIGNvbXBhcmUgdGhlIG11dGFudCBhbmQgd2lsZCB0eXBlIHNhbXBsZXMgZmlyc3QuCgpJbiBvcmRlciB0byBjaGVjayB0aGF0IG15IHNhbXBsZSBpbmZvcm1hdGlvbiBoYWQgYmVlbiBhc3NpZ25lZCBjb3JyZWN0bHkgaSB1c2VkIHRoZSBjb2xEYXRhIGZ1bmN0aW9uIHRvIGNoZWNrIHRoYXQgZWFjaCBzYW1wbGUgaGFkIHRoZSBjb3JyZWN0IHRyZWF0bWVudCBhbmQgZ2Vub3R5cGUgYXNzaWduZWQgdG8gdGhlbS4KYGBge3J9CiNJbml0aWFsaXNlIHRoZSBkZXNlcTIgcGFja2FnZQpsaWJyYXJ5KERFU2VxMikKCiNDb21iaW5lIG1ldGFkYXRhIGFuZCBjb3VudCBkYXRhIGludG8gc2luZ2xlIGRkcyBvYmplY3QKZGRzIDwtIERFU2VxRGF0YVNldEZyb21NYXRyaXgoY291bnREYXRhID0gY291bnRzLGNvbERhdGEgPSBzYW1wbGVpbmZvLCBkZXNpZ24gPSB+R2Vub3R5cGUpCgojQ2hlY2tpbmcgdGhhdCBtZXRhZGF0YSBoYXMgYmVlbiBjb3JyZWN0bHkgYXNzaWduZWQKY29sRGF0YShkZHMpCmBgYAoKQWZ0ZXIgaW5zcGVjdGluZyB0aGUgY29sRGF0YSBwcm9wZXJ0eSBvZiB0aGUgZGRzIG9iamVjdCBpdCBpcyBhcHBhcmVudCB0aGF0IHRoZSBzYW1wbGUgaWQgY29sdW1uIGRpZCBub3QgaGF2ZSBhIG5hbWUuIFRoaXMgaXMgZHVlIHRvIHRoZSBmYWN0IHRoYXQgZGVzZXEgYXV0b21hdGljYWxseSBpbXBvcnRzIHRoZSBzYW1wbGUgbmFtZXMgZnJvbSB0aGUgY3N2IGZpbGUgYXMgcm93bmFtZXMgaW4gdGhlIGRlc2VxIGRhdGFzZXQuIFRoaXMgbWF5IG1ha2UgYW5hbHlzaXMgZGlmZmljdWx0IGlmIEkgd2lzaCB0byBzZWxlY3Qgc2FtcGxlcyBiYXNlZCBvbiB0aGVpciBuYW1lLCBzbyBJIHdyb3RlIGEgY29kZSBibG9jayB0aGF0IGNyZWF0ZXMgYSBzYW1wbGUgaWQgY29sdW1uLCB3aXRoIGFsbCB0aGUgc2FtcGxlIGlkcyBhbmQgYWRkcyB0aGlzIHRvIHRoZSBkZXNlcSBkYXRhc2V0LlRoaXMgdXNlcyB0aGUgY2JpbmQgZnVuY3Rpb24gd2hpY2ggYWxsb3dzIHlvdSB0byBjcmVhdGUgYSBuZXcgY29sdW1uIGFuZCBhc3NpZ24gdmFsdWVzIHRvIHRoZSBzdWJzZXF1ZW50IHJvd3MuIEkgbGVhcm5lZCBob3cgdG8gZG8gdGhpcyB0aHJvdWdoIHJlYWRpbmcgdGhlIFIgZG9jdW1lbnRhdGlvbiBmb3IgY2JpbmQoKTogaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2Jhc2UvdmVyc2lvbnMvMy42LjIvdG9waWNzL2NiaW5kCgpgYGB7cn0KI0NyZWF0ZSBhIG5ldyBjb2x1bW4gaW4gdGhlIGNvbERhdGEgaXRlbSBjb3Jyb3Nwb25kaW5nIHRvIHRoZSByb3duYW1lcyAKY29sRGF0YShkZHMpIDwtIGNiaW5kKE5hbWUgPSByb3duYW1lcyhjb2xEYXRhKGRkcykpLCBjb2xEYXRhKGRkcykpCgojSW5zcGVjdCByZXN1bHRzCmNvbERhdGEoZGRzKQpgYGAKVGhlIHJvd25hbWVzIGFyZSBub3cgbnVtYmVycyB3aGljaCBJIGNhbnQgZ2V0IHJpZCBvZiBob3dldmVyIEkgd2lsbCBiZSBhYmxlIHRvIHVzZSB0aGUgTmFtZSBjb2x1bW4gdG8gc2VsZWN0IHNhbXBsZXMsIHRoZXJlZm9yIHRoZSByb3cgbnVtYmVycyBhcmUgaXJyZWxldmFudCBhbmQgc2hvdWxkbnQgaW50ZXJmZXJlIHdpdGggYW55IGFuYWx5c2lzICh0aGlzIHJlbWFpbnMgdG8gYmUgc2VlbikuCgpGdXR1cmUgcmVzZWFyY2ggaGFzIHJldmVhbGVkIHRoYXQgSSBjb3VsZCd2ZSBqdXN0IHVzZWQgdGhlIHJvd25hbWVzKCkgZnVuY3Rpb24gdG8gc2VsZWN0IHRoZSBzYW1wbGVzIGhvd2V2ZXIgSSBwcmVmZXIgdG8gaGF2ZSB0aGVtIGluIGEgbmFtZWQgY29sdW1uIGFzIGl0IG1ha2VzIHRoZSBkYXRhIGVhc2llciB0byByZWFkIGluIG15IG9waW5pb24uCgojIDIxLzEwLzIwMjAgUXVhbGl0eSBhbmFseXNpcyBvZiB0aGUgZGF0YSAKSW4gb3JkZXIgdG8gY2hlY2sgdGhhdCBzYW1wbGVzIGFyZSBsYWJlbGxlZCBjb3JyZWN0bHkgYW5kIHRoYXQgdGhlIGNvdW50IGRhdGEgZm9sbG93cyBhIG5vcm1hbCBkaXN0cmlidXRpb24gSSBtdXN0IGZpcnN0IGNvbmR1Y3QgcXVhbGl0eSBhbmFseXNpcyBvZiB0aGUgY291bnQgZGF0YS4KCkluIG9yZGVyIHRvIHZpc3VhbGlzZSB0aGUgZGlzdHJpYnV0aW9uIG9mIGNvdW50IGRhdGEgaXQgbXVzdCBmaXJzdCBiZSB0cmFuc2Zvcm1lZCB0byBhY2NvdW50IGZvciBsYXJnZSBkaWZmZXJlbmNlcyBpbiBjb3VudHMgdGhhdCBtaWdodCBza2V3IHRoZSBkYXRhLiBkZXNlcTIgaGFzIHR3byBpbmJ1aWx0IGZ1bmN0aW9ucyB0byBkbyB0aGlzOiBybG9nKCkgYW5kIHZzdCgpLiBCb3RoIG9mIHRoZXNlIGRvIGVzc2VudGlhbGx5IHRoZSBzYW1lIHRoaW5nOyB0aGV5IGJvdGggY29uZHVjdCBhIGxvZzIgdHJhbnNmb3JtYXRpb24gb24gdGhlIGRhdGEuIEkndmUgc2VlbiBhIGxvdCBvZiBwZW9wbGUgaW4gb25saW5lIHRocmVhZHMgc2F5aW5nIHRoYXQgdnN0IGlzIGJldHRlciBhbmQgZmFzdGVyIGZvciBsYXJnZSBkYXRhc2V0cywgc28gaSB3aWxsIHVzZSB0aGF0LiAKCmBgYHtyfQojVHJhbnNmb3JtIHRoZSBkYXRhCnZzZCA9IHZzdChkZHMsIGJsaW5kID0gVFJVRSkKYGBgCgojIyMgQm94cGxvdCBvZiBub3JtYWxpc2VkIGNvdW50IGRhdGEKSSB1c2VkIGEgYm94cGxvdCB0byBhc3Nlc3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgdHJhbnNmb3JtZWQgY291bnQgZGF0YS4gVGhlIGJsdWUgbGluZSByZXByZXNlbnRzIHdoZXJlIHRoZSBtZWRpYW5zIHBmIGVhY2ggc2FtcGxlIGxpbmVzIHVwLiBJbml0aWFsbHkgdGhlIHNhbXBsZSBsYWJlbHMgb24gdGhlIHggYXhpcyB3ZXJlIGN1dCBvZmYgc28gSSBoYWQgdG8gcmVzaXplIHRoZSBmaWd1cmUgdG8gY29tcGVuc2F0ZSBmb3IgdGhpcy4gVGhpcyBibG9nIHByb3ZlZCBhIHZlcnkgdXNlZnVsIHJlc291cmNlIHdoZW4gbGVhcm5pbmcgaG93IHRvIGRvIHRoaXM6Cmh0dHA6Ly96ZXZyb3NzLmNvbS9ibG9nLzIwMTcvMDYvMTkvdGlwcy1hbmQtdHJpY2tzLWZvci13b3JraW5nLXdpdGgtaW1hZ2VzLWFuZC1maWd1cmVzLWluLXItbWFya2Rvd24tZG9jdW1lbnRzLwoKYGBge3IgfQpwYXIoY2V4LmF4aXM9MC42KQpib3hwbG90KGFzc2F5KHZzZCksIHlsYWI9IkxvZzIgY291bnRzIixsYXM9MixtYWluPSJOb3JtYWxpc2VkIERpc3RyaWJ1dGlvbnMiLCBuYW1lcyA9IHZzZCROYW1lKQoKIyBBZGRlZCBhIGJsdWUgaG9yaXpvbnRhbCBsaW5lIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIG1lZGlhbiBsb2dDUE0KYWJsaW5lKGg9bWVkaWFuKGFzc2F5KHZzZCkpLCBjb2w9ImJsdWUiKQpgYGAKVGhlIG1lZGlhbnMgb2YgYWxsIHRoZSBkYXRhIGFwcGVhciB0byBsaW5lIHVwIGFzaWRlIGZyb20gc29tZSBzbGlnaHQgdmFyaWFiaWxpdHkgaW4gdGhlIG11dGFudCB0cmVhdGVkIHNhbXBsZXMsIHR3byBvZiB3aGljaCBzaG93IG1lZGlhbnMgc2xpZ2h0bHkgYWJvdmUgdGhlIGxpbmUuIGFzIGEgcmVzdWx0IEkgY2FuIGNvbmNsdWRlIHRoYXQgdGhlc2UgZGF0YSBoYXZlIGJlZW4gbm9ybWFsaXplZCBzdWNjZXNzZnVsbHkuCgpTaW5jZSBteSBkYXRhIGlzIG5vcm1hbGlzZWQgSSBjYW4gY29uZHVjdCB0aGUgb3RoZXIgcXVhbGl0eSBhbmFseXNpcyB0b21vcnJvdy4KCiMgMjIvMTAvMjAyMCBQcmluY2lwbGUgY29tcG9uYW50IGFuYWx5c2lzIApJbiBvcmRlciB0byB2aXN1YWxpc2UgdGhlIHJlbGF0aXZlIHNpbWlsYXJpdHkgb2Ygc2FtcGxlcyBJIGNhbiB1c2UgYSBQQ0EgcGxvdC4gVGhpcyBjb21wYXJlcyBzYW1wbGVzIGJhc2VkIG9uIHRoZWlyIHR3byBwcmluY2lwbGUgY29tcG9uZW50cywgYW5kIHBsb3RzIHRoZWlyIHNpbWlsYXJpdHkgb24gYSB0d28gZGltZW5zaW9uYWwgZ3JpZCwgcmVsYXRpdmUgdG8gYWxsIG90aGVyIHNhbXBsZXMgaW4gdGhlIHN0dWR5LiBTYW1wbGVzIHRoYXQgYXJlIHNpbWlsYXIgd2lsbCBsaWtlbHkgZm9ybSBjbHVzdGVycyB0b2dldGhlciB3aXRoaW4gYSBxdWFkcmFudCBvZiB0aGUgZ3JhcGguIElOIGEgcGVyZmVjdCB3b3JsZCB3ZSBzaG91bGQgZXhwZWN0IHNpZ25pZmljYW50IG92ZXJsYXAgYmV0d2VlbiByZXN1bHRzIG9mIHRoZSBzYW1lIGdyb3VwIGhvd2V2ZXIgdGhlcmUgaXMgbGlrZWx5IHRvIGJlIHNvbWUgYmlvbG9naWNhbCB2YXJpYWJpbGl0eSB0aGF0IGltcGFjdHMgdGhpcy4gQXMgbG9uZyBhcyB0aGVyZSdzIG5vIGRpc3RpbmN0IGNyb3Nzb3ZlciBiZXR3ZWVuIGdyb3VwcyB0aGVuIEkgY2FuIGNvbmNsdWRlIHRoZSBzYW1wbGVzIGFyZSBjb3JyZWN0bHkgbGFiZWxsZWQuCgpJbiBvcmRlciB0byBjcmVhdGUgdGhlIHBsb3QgSSBhbSB1c2luZyB0d28gcGFja2FnZXM6IGRlc2VxMiBhbmQgZ2dwbG90LiBkZXNlcTIgaGFzIGEgZnVuY3Rpb24gZGVkaWNhdGVkIHRvIG1ha2luZyBwY2EgcGxvdHMgb2YgZ2VuZXRpYyBkYXRhLCB3aGljaCBpIHdpbGwgdXNlIHRvIG1ha2UgdGhlIHBsb3QgaXRzZWxmLiBJIGNhbiB0aGVuIHVzZSBnZ3Bsb3QgdG8gbW9kaWZ5IHRoaXMgZ3JhcGggYW5kIG1ha2UgbW9kaWZpY2F0aW9ucyB0byBtYWtlIGl0IGVhc2llciB0byB2aXN1YWxpc2UgdGhlIGRhdGEuCgpNeSBzdXBlcnZpc29yIHRhdWdodCBtZSBob3cgdG8gbWFrZSBhIHBjYSBwbG90IGZvciBvbmUgb2YgbXkgY29tcGFyaXNvbnMsIGhvd2V2ZXIgYWZ0ZXIgbG9va2luZyBhdCB0aGUgZG9jdW1lbnRhdGlvbiBmcm9tIGRlc2VxMiBpdCBhcHBlYXJzIHRoYXQgSSBjYW4gZGVmaW5lIGFuIGludGVyZXN0IGdyb3VwIGFzIGEgdmVjdG9yIHRoYXQgY292ZXJzIGFsbCBzYW1wbGUgY29uZGl0aW9ucyBkZWZpbmVkIGluIHRoZSBjb2xEYXRhIChtZXRhZGF0YSkuIE15IHBjYSBwbG90IHdpbGwgdGhlcmVmb3IgYmUgb25lIHBsb3QgdGhhdCBjb3ZlcnMgYWxsIHNhbXBsZXMgaW4gdGhlIHN0dWR5LgoKSSBnZW5lcmF0ZWQgdGhlIHBsb3Qgd2l0aCB0aGUgaW50ZXJlc3QgZ3JvdXBzIGJlaW5nIHRyZWF0bWVudCBhbmQgZ2Vub3R5cGUgaW4gb3JkZXIgdG8gZ2FpbiBhbiBvdmVydmlldyBvZiBob3cgZWFjaCBncm91cCBvZiBzYW1wbGVzIHdhcyBkaWZmZXJlbnQuIEkgbGltaXRlZCB0aGUgWCBhbmQgWSBzY2FsZXMgYWZ0ZXIgZXhwZXJpbWVudGluZyB0byBzZWUgd2hpY2ggc2V0dGluZ3MgZ2F2ZSB0aGUgYmVzdCBzaXplZCBncmFwaCB3aGVyZSBhbGwgdGhlIGRhdGEgd2FzIHZpc2libGUuIEkgdXNlZCB0aGUgZmlndXJlLmhlYWRpbmcgYW5kIGZpZ3VyZS5oZWlnaHQgcGFyYW1ldGVycyBpbiB0aGUgY2h1bmsgb3B0aW9ucyB0byByZXNpemUgdGhlIGdyYXBoIHRvIGEgc3VpdGFibGUgc2l6ZSBlbnN1cmluZyB2aXNpYmlsaXR5LgoKZ2dscG90IHdhcyB1c2VkIHRvIHR1cm4gZWFjaCBkYXRhIGludG8gYSBzYW1wbGUgbGFiZWwuCgpgYGB7ciBmaWd1cmUud2lkdGggPSAxNSwgZmlndXJlLmhlaWdodCA9IDE1fQojSW5pdGlhbGlzZSB0aGUgZ2dwbG90MiBsaWJyYXJ5CmxpYnJhcnkoZ2dwbG90MikKCgojQ3JlYXRlIHRoZSBwY2EgcGxvdCwgaW50Z3JvdXAgaXMgYSB2ZWN0b3Igd2l0aCBnZW5vdHlwZSBhbmQgdHJlYXRtZW50CnBsb3QgPSBwbG90UENBKHZzZCwgaW50Z3JvdXAgPSBjKCJHZW5vdHlwZSIsIlRyZWF0bWVudCIpKQoKI3ByaW50IHRoZSBwbG90IHdpdGggc2FtcGxlIGluZm9ybWF0aW9uIGFuZCBzY2FsZSBtb2RpZmljYXRpb25zIHVzaW5nIGdncGxvdDIKcGxvdCArIGdlb21fbGFiZWwoYWVzKGxhYmVsID0gdnNkJE5hbWUpKSArICBjb29yZF9maXhlZCh4bGltID0gYygtMzAsMzApLCB5bGltID0gYygtMjAsMjApKQpgYGAKVGhlIFBDQSBwbG90IHNob3dzIGRpc3RpbmN0IHNhbXBsZSBjbHVzdGVyaW5nIGJhc2VkIG9uIGdlbm90eXBlIGFuZCB0cmVhdG1lbnQgZ3JvdXAuIEl0IGFwcGVhcnMgdGhlIHdpbGR0eXBlIHRyZWF0ZWQgYW5kIG11dGFudCB0cmVhdGVkIHNhbXBsZXMgYXJlIG1vcmUgc2ltaWxhciB0byBlYWNoIG90aGVyIHRoYW4gdGhlaXIgbm9uIHRyZWF0ZWQgY291bnRlcnBhcnRzLiBUaGVyZSBhcHBlYXJzIHRvIGJlIG1vc3QgdmFyaWF0aW9uIHdpdGhpbiB0aGUgbXV0YW50IHRyZWF0ZWQgZ3JvdXAsIHdpdGggQ1lQX01VVC5IQzEgYmVpbmcgc2VwZXJhdGVkIGZyb20gdGhlIG90aGVyIHR3byBzYW1wbGVzLiBUaGVzZSBzbWFsbCBkaWZmZXJlbmNlcyBhcmUgbGlrZWx5IGR1ZSB0byBiaW9sb2dpY2FsIHZhcmlhYmlsaXR5IHdpdGhpbiB0aGUgc2FtcGxlcyBhbmQgYXJlIHVubGlrZWx5IHRvIGVmZmVjdCByZXN1bHRzLgoKY2x1c3RlciBkZW5kb3JvZ3JhbXMgYXJlIGFub3RoZXIgbWV0aG9kIG9mIGFzc2Vzc2luZyBzaW1pbGFyaXR5LiBUaGVzZSBwcm92aWRlIGEgdHJlZSB3aXRoIGJyYW5jaGVzIGNvbm5lY3Rpbmcgc2FtcGxlcyB0aGF0IGFyZSByZWxhdGVkIGkuZSBtb3JlIHNpbWlsYXIuIEhvcGVmdWxseSB0aGUgc2FtcGxlcyB3aWxsIGJyYW5jaCBiYXNlZCBvbiB0aGVpciBnZW5vdHlwZSBhbmQgdHJlYXRtZW50IGdyb3VwLCBpbmRpY2F0aW5nIGRpZmZlcmVuY2VzIGluIGdlbmUgZXhwcmVzc2lvbiBiZXR3ZWVuIHRoZXNlIGZhY3RvcnMuCgojIyMgU2FtcGxlIGNsdXN0ZXJpbmcgYW5hbHlzaXMKYGBge3J9CiNQTG90IERlbmRvZ3JhbSAKcGxvdChoY2x1c3QoZGlzdCh0KGFzc2F5KHZzZCkpKSksIGxhYmVscyA9IHZzZCROYW1lKQpgYGAKVGhlIGNsdXN0ZXIgZGVuZG9ncmFtIHNob3dzIHRoYXQgdGhlcmUgaXMgYSBsYXJnZSBhbW91bnQgb2Ygc2ltaWxhcml0eSB3aXRoaW4gZ3JvdXBzIGFwYXJ0IGZyb20gdGhlIG11dGFudCB0cmVhdGVkIHNhbXBsZXMgd2hlcmUgQ1lQX01VVC5IQzMgaXMgc2hvd24gdG8gYmUgc2xpZ2h0bHkgbW9yZSBzaW1pbGFyIHRvIHRoZSB3aWxkIHR5cGUgdHJlYXRlZCBzYW1wbGVzLiAKCgojIyMgQ2x1c3RlciBoZWF0bWFwCkluIG9yZGVyIHRvIGdldCBhIG1vcmUgcXVhbnRpdGF0aXZlIG92ZXJ2aWV3IG9mIHNhbXBsZSBzaW1pbGFyaXR5IGEgaGVhdG1hcCBjYW4gYmUgZ2VuZXJhdGVkIGZyb20gdGhlIGNvcnJlbGF0aW9ucyBpbiB0aGUgY291bnQgZGF0YS4gSW4gb3JkZXIgdG8gZG8gdGhpcyBJIHVzZWQgdGhlIHBoZWF0bWFwIGxpYnJhcnkgd2hpY2ggYWxsb3dzIGZvciBnZW5lcmF0aW9uIG9mIGhlYXRtYXBzLiBUaGUgaGVhdG1hcCB3aWxsIGNvbXBhcmUgZWFjaCBzYW1wbGUgdG8gb25lIGFub3RoZXIsIHdpdGggdGhlIGRlZ3JlZSBvZiByZWRuZXNzIG9mIGVhY2ggdGlsZSBzaG93aW5nIHNhbXBsZSBzaW1sYXJpdHkuIEkgc2hvdWxkIGV4cGVjdCB0byBzZWUgZGVlcCByZWQgd2hlcmUgc2FtcGxlcyBvZiB0aGUgc2FtZSBncm91cCBhcmUgY29tcGFyZWQgYW5kIGRlZXAgYmx1ZSB3aGVyZSBzYW1wbGVzIG9mIGRpZmZlcmluZyBncm91cHMgYXJlIGNvbXBhcmVkLiBBcyBhIHJlc3VsdCB0aGUgaGVhdG1hcCBzaG91bGQgZGlzcGxheSBjbHVzdGVycyBvZiByZWQgYW5kIGJsdWUuIEkgdXNlZCB0aGUgbWV0YWRhdGEgbWVudGlvbmVkIGVhcmxpZXIgdG8gYW5ub3RhdGUgdGhlIGNvbHVtbnMgYW5kIHJvd3Mgb2YgdGhlIGhlYXRtYXAgYmFzZWQgb24gdGhlIGdlbm90eXBlIGFuIHRyZWF0bWVudCBvZiBlYWNoIHNhbXBsZS4KCmBgYHtyfQojSW5pdGlhbGlzZSB0aGUgcGhlYXRtYXAgbGlicmFyeQpsaWJyYXJ5KHBoZWF0bWFwKQoKI1JldHJpZXZlIHRoZSBtZXRhZGF0YSBmb3IgYW5ub3RhdGlvbgpzYW1wbGVpbmZvID0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKGRkcylbLGMoJ1RyZWF0bWVudCcsJ0dlbm90eXBlJyldKQoKI1JldHJpZXZlIG5vcm1hbGlzZWQgY291bnQgZGF0YSAKYXNzYXkgPSBhc3NheSh2c2QpCgojQ2FsY3VsYXRlIGNvcnJlbGF0aW9ucwphc3NheV9jb3IgPC0gY29yKGFzc2F5KQoKCiMgMS4gT3BlbiBqcGVnIGZpbGUKcG5nKCJGaWd1cmVzL3FhIGhlYXRhbXAiLCB3aWR0aCA9IDcwMCkKIyAyLiBDcmVhdGUgdGhlIHBsb3QKI1Bsb3QgY29ycmVsYXRpb25zIG9uIGFubm90YXRlZCBoZWF0bWFwCnBoZWF0bWFwKGFzc2F5X2NvciwKICAgICAgICAgYW5ub3RhdGlvbiA9IHNhbXBsZWluZm8sIAogICAgICAgICBhbm5vdGF0aW9uX3JvdyA9IHNhbXBsZWluZm8sCiAgICAgICAgIGxhYmVsc19yb3cgPSB2c2QkTmFtZSwKICAgICAgICAgbGFiZWxzX2NvbCA9IHZzZCROYW1lKQojIDMuIENsb3NlIHRoZSBmaWxlCmRldi5vZmYoKQpgYGAKVGhlIGhlYXRtYXAgc2hvd3MgY2x1c3RlcmluZyB3aGVyZSBzaW1pbGFyIGdyb3VwcyBhcmUgY29tcGFyZWQuIEl0IGFwcGVhcnMgdGhlcmUgaXMgYSBsYXJnZSBhbW91bnQgb2Ygc2ltaWxhcml0eSBiZXR3ZWVuIHdpbGQgdHlwZSBhbmQgbXV0YW50IHRyZWF0ZWQgc2FtcGxlcywgYW5kIGEgZ3JlYXRlciBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIHR3byBnZW5vdHlwZXMgd2hlbiB1bnRyZWF0ZWQuIFRoZXJlIGFsc28gYXBwZWFycyB0byBiZSBhIGxhcmdlIGFtb3VudCBvZiB2YXJpYWJpbGl0eSB3aXRoaW4gdGhlIG11dGFudCB1bnRyZWF0ZWQgZ3JvdXAsIHdoaWNoIGluZGljYXRlcyBiaW9sb2dpY2FsIGRpZmZlcmVuY2VzIGluIGdlbmUgZXhwcmVzc2lvbiBiZXR3ZWVuIHRoZSBzYW1wbGVzLgoKCiMgMjcvMTAvMjAyMCBEaWZmZXJlbnRpYWwgZXhwcmVzc2lvbiBhbmFseXNpczogZXhwZXJpbWVudGFsIGRlc2lnbgpUaGUgYWltcyBvZiB0aGUgc3R1ZHkgYXJlIHRvIGlkZW50aWZ5IGN5cDIxYTIgZGVwZW5kYW50IGdsdWNvY29ydGljb2lkIHJlZ3VsYXRlZCBnZW5lZCBhbmQgdG8gYXNzZXNzIHRoZSBlZmZlY3RzIG9mIGh5ZHJvY29ydHNpb25lIG9uIHRoZSBtdXRhbnQgcGhlbm90eXBlLiBJbiBvcmRlciB0byBhc3Nlc3MgdGhpcyBJIHdpbGwgbWFrZSBtdWx0aXBsZSBwYWlyIHdpc2UgZ2VuZSBleHByZXNzaW9uIGNvbXBhcmlzaW9uczoKCiBXVCBWIE1VVCB0byBhbmFseXNlIHRoZSBzdWNjZXNzIG9mIG11dGF0aW9uIGFuZCBpdHMgZWZmZWN0IG9uIGdlbmUgdHJhbnNjcmlwdGlvbgogCiBNVVQgdHJlYXRlZCBWIE1VVCB1bnRyZWF0ZWQgdG8gYXNzZXNzIHRoZSBlZmZlY3RzIG9mIHRoZSB0cmVhdG1lbnQgCiAKIFdUIFYgTVVUIHRyZWF0ZWQgdG8gYXNzZXNzIGhvdyBkaWZmZXJlbnQgdGhlIHRyZWF0ZWQgbXV0YW50cyBhcmUgZnJvbSB0aGUgbm9ybSAKIAogV1QgdHJlYXRlZCBWIFdUIHVudHJlYXRlZCB0byBhc3Nlc3MgdGhlIGVmZmZlY3RzIG9mIGVsZXZhdGVkIGdsdWNvY29ydGljb2lkIHNpZ25hbGxpbmcgb24gZ2VuZSB0cmFuc2NyaXB0aW9uCiAKIEkgdGhlbiBhaW0gb24gdmlzdWFsaXNpbmcgdGhpcyBkYXRhIHdpdGggbWV0aG9kcyBzdWNoIGFzIGhlYXRtYXBzIGFuZCB2b2xjYW5vIHBsb3RzLgogCiA0IGNvbXBhcmlzb25zIG1heSBiZSB0b28gbWFueSB0byB0YWxrIGFib3V0IGluIG15IGZpbmFsIHJlcG9ydCBhbmQgaWYgdGhhdCdzIHRoZSBjYXNlIHRoZW4gaSB3aWxsIHBpY2sgb3V0IHRoZSBtb3N0IGludGVyZXN0aW5nIG9uZXMuCiAKIEluIG9yZGVyIHRvIGFuYWx5c2UgdGhpcyBkYXRhIGkgd2lsbCBuZWVkIHRvIG1ha2Ugc3Vic2V0cyBvZiB0aGUgZGRzIG9iamVjdCBpIGNyZWF0ZWQgZWFybGllciBjb3Jyc3BvbmRpbmcgdG8gZWFjaCBvZiB0aGUgY29tcGFyaXNvbnMgdGhhdCBpIHdpc2ggdG8gbWFrZS4gT25jZSBpIGhhdmUgZmlndXJlZCBvdXQgaG93IHRvIGRvIHRoaXMgaSBjYW4gY29uZHVjdCBteSBhbmFseXNpcyBhbmQgdmlzdWFsaXNlIHRoZSBkYXRhCiAKIyMjU3Vic2V0dGluZyB0aGUgZGVzZXEgZGF0YXNldApBZnRlciByZWFkaW5nIHRocm91Z2ggdGhlIGRvY3VtZW50YXRpb24gZm9yIHRoZSBkZXNlcTIgcGFja2FnZSBJdCBzZWVtcyBpIGNhbiBzdWJzZXQgdGhlIGRhdGEgYnkgZ25lcmF0aW5nIGRpZmZlcmVudCBkYXRhc2V0cyBjb3Jyb3Nwb25kaW5nIHRvIGVhY2ggcGFpcndpc2UgYW5hbHlzaXMgZnJvbSBteSBvcmlnaW5hbCBkZHMgb2JqZWN0LiBJdCBpcyBhIHNpbXBsZSBjYXNlIG9mIHJldHJpZXZpbmcgdGhlIGNvdW50cyBmb3IgZWFjaCBzYW1wbGUgaW4gdGhlIGdyb3VwIHRoYXQgaSB3aXNoIHRvIGNvbWFwcmUgYW5kIGNyZWF0aW5nIGEgbmV3IGRlc2VxZGF0YXNldCBjb250YWluaW5nIGp1c3QgdGhhdCBpbmZvcm1hdGlvbi4gT25jZSBpIGhhdmUgdGhpcyBJIGNhbiBydW4gdGhlIGRlc2VxKCkgZnVuY3Rpb24gd2hpY2ggd2lsbCB0cmFuc2Zvcm0gYW5kIGFuYWx5c2UgbXkgZGF0YSwgY2FsY3VsYXRpbmcgdGhlIGZvbGRjaGFuZ2UgaW4gZ2VuZSBleHByZXNzaW9uIGFuZCBhc3NpZ25pbmcgc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlLiAKCklmIGkgY2FudCBnZXQgdGhlIHN1YnNldHRpbmcgdG8gd29yayBhbiBhbHRlcm5hdGl2ZSBtZXRob2Qgd291bGQgYmUgdG8gbWF1bmFsbHkgY29weSBhbmQgcGFzdGUgdGhlIHBhaXJ3aXNlIGRhdGEgaW50byBpbmRpdmlkdWFsIGNzdiBmaWxlcywgYW5kIHRoZW4gcmVhZCB0aGF0IGRhdGEgaW50byBSIHNlcGVyYXRlbHksIHdoaWNoIHdhcyByZWNvbW1lbmRlZCBieSBkciBjdW5saWZmZS4gSG93ZXZlciBJIHdpc2ggdG8gdHJ5IHN1YnNldHRpbmcgdGhlIGRhdGEgaW4gUiBmaXJzdCBhcyBpdCB3aWxsIGVuc3VyZSB0aGF0IG5vIGh1bWFuIGVycm9yIG9jY3VyZWQgdGhyb3VnaCBtdW51YWwgY29weWluZyBhbmQgcGFzdGluZyBvZiB0aGUgZGF0YS4gSWYgaSBjYW50IGdldCB0aGlzIHRvIHdvcmsgdGhlbiBpIHdpbGwgbWFudWFsbHkgY29weSBhbmQgcGFzdGUgdGhlIGRhdGEgaW50byBleGNlbCBmaWxlcy4KCiMjIyBXVCB1bnRyZWF0ZWQgdnMgbXV0YW50IHVudHJlYXRlZCAKVGhlIGZvbGxvd2luZyBzaG91bGQgc3VjY2Vzc2Z1bGx5IGNyZWF0ZSBteSBmaXJzdCBzdWJzZXQgKFdUIFYgTVVUKQpgYGB7cn0KI1JldHJpZXZlIGNvdW50cyBmb3IgdW50cmVhdGVkIHNhbXBsZXMKZGRzX2dlbm90eXBlID0gZGRzWyx3aGljaChkZHMkVHJlYXRtZW50ID09ICJ1bnRyZWF0ZWQiKV0KCiNTZXQgdGhlIGRlc2lnbiB0byBjb21wYXJlIGV4cHJlc3Npb24gYmV0d2VlbiBnZW5vdHlwZXMKZGVzaWduKGRkc19nZW5vdHlwZSkgPSB+R2Vub3R5cGUKCiNVc2UgREVTZXEyIHRvIGFuYWx5c2UgZGF0YQpkZV9nZW5vdHlwZSA9IERFU2VxKGRkc19nZW5vdHlwZSkKCiNHZW5lcmF0ZSByZXN1bHRzLCB1c2luZyBNVVQgYXMgYmFzZWxpbmUgZm9yIGxvZyBmb2xkIGNoYW5nZQpnZW5vdHlwZV9yZXN1bHRzID0gcmVzdWx0cyhkZV9nZW5vdHlwZSwgYygnR2Vub3R5cGUnLCdNVVQnLCdXVCcpKQpgYGAKClRnZSBkZXNlcSBmdW5jdGlvbiBjYWxjdWxhdGVzIGxvZyBmb2xkIGNoYW5nZSBpbiBnZW5lIGV4cHJlc3Npb24uIGluIHRoaXMgY2FzZSBzaW5jZSBpIHNldCB0aGUgY29tcGFyaXNvbiB0byBtdXRhbnQgdnMgd3QgaXQgd2lsbCBjYWxjdWxhdGUgdGhlIGNoYW5nZSBpbiBtdXRhbnQgdG8gd2lsZCB0eXBlLiBBIHBvc2l0aXZlIGZvbGQgY2hhbmdlIGluZGljYXRlcyBhIGdyZWF0ZXIgZXhwcmVzc2lvbiBpbiB0aGUgbXV0YW50LCB3aWxzdCBhIG5lZ2F0aXZlIGZvbGQgY2hhbmdlIGluZGljYXRlcyBkZWNyZWFzZWQgZXhwcmVzc2lvbi4KRGVzZXEgYWxzbyBjYWxjdWxhdGVzIHRoZSBhZGp1c3RlZCBwIHZhbHVlLCB3aGljaCBnaXZlcyBpbmRpY2F0aW9uIG9mIHN0YXRpc3RpY2FsIHNpZ25pZmljYW5jZS4gVGhlIGxvd2VyIHRoaXMgaXMgdGhlIG1vcmUgc2lnbmlmaWNhbnQgdGhlIHJlc3VsdC4KClNpbmNlIHRoaXMgc3VjY2Vzc2Z1bGx5IHN1YnNldHRlZCB0aGUgZGF0YSwgYW5kIGkgbm93IGhhdmUgYW4gb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8ganVzdCB0aGUgbXV0YW50IGFuZCB3aWxkdHlwZSB1bnRyZWF0ZWQgc2FtcGxlcywgSSB3aWxsIG5vdyBjcmVhdGUgc3Vic2V0cyBmb3IgdGhlIHJlc3Qgb2YgdGhlIGRhdGEuCgojIyMgTXV0YW50IHRyZWF0ZWQgdnMgbXV0YW50IHVudHJlYXRlZApXaGVuIGNoYW5naW5nIHRoZSBkZXNpZ24gdG8gY29tcGFyZSBiZXR3ZWVuIHRyZWF0bWVudCBncm91cHMgaSBjYW1lIGFjY3Jvc3MgYSBwcm9ibGVtLiBXaGVuIGRlc2VxIHJlYWQgaW4gdGhlIHNhbXBsZSBpbmZvIGl0IGFzc2lnbmVkIHRoZSB0cmVhdG1lbnQgY29sdW1uIHRvIGJlIGEgY2hhcmFjdGVyIHZlY3RvciBhcyBvcHBvc2VkIHRvIGEgZmFjdG9yLiBJbiBvcmRlciB0byB1c2UgdGhlIFRyZWF0bWVudCBhcyBhIGRlc2lnbiBJIG5lZWQgdG8gY29udmVydCBpdCB0byBhIGZhY3RvciB3aGljaCBJIGNhbiBkbyB1c2luZyB0aGUgYXMuZmFjdG9yKCkgZnVuY3Rpb24gd2hpY2ggaSBsZWFybmVkIGhvdyB0byB1c2UgaGVyZToKaHR0cHM6Ly93d3cucmRvY3VtZW50YXRpb24ub3JnL3BhY2thZ2VzL2gyby92ZXJzaW9ucy8yLjQuMy4xMS90b3BpY3MvYXMuZmFjdG9yCgpgYGB7cn0KI0NvbnZlcnQgdGhlIFRyZWF0bWVudCBjaGFyYWN0ZXIgdmVjdG9yIHRvIGZhY3RvcgpkZHMkVHJlYXRtZW50ID0gYXMuZmFjdG9yKGRkcyRUcmVhdG1lbnQpCmBgYAoKSSBjYW4gbm93IHN1YnNldCB0aGUgZGF0YSwgdGhpcyB0aW1lIHVzaW5nIFRyZWF0bWVudCBhcyB0aGUgZGVzaWduLgpgYGB7cn0KI1JldHJpZXZlIGNvdW50cyBmb3IgbXV0YW50IHNhbXBsZXMKZGRzX211dHRyZWF0bWVudCA9IGRkc1ssd2hpY2goZGRzJEdlbm90eXBlID09ICJNVVQiKV0KCiNTZXQgdGhlIGRlc2lnbiB0byBjb21wYXJlIGV4cHJlc3Npb24gYmV0d2VlbiB0cmVhdG1lbnRzCmRlc2lnbihkZHNfbXV0dHJlYXRtZW50KSA9IH5UcmVhdG1lbnQKCiNVc2UgREVTZXEyIHRvIGFuYWx5c2UgZGF0YQpkZV9tdXR0cmVhdG1lbnQgPSBERVNlcShkZHNfbXV0dHJlYXRtZW50KQoKI1N0b3JlIHJlc3VsdHMKbXV0cmVhdG1lbnRfcmVzdWx0cyA9IHJlc3VsdHMoZGVfbXV0dHJlYXRtZW50LCBjb250cmFzdCA9IGMoJ1RyZWF0bWVudCcsJ3RyZWF0ZWQnLCd1bnRyZWF0ZWQnKSkKYGBgCiMjIyBNdXRhbnQgdHJlYXRlZCB2cyBXVApTdWJzZXR0aW5nIHRoaXMgZGF0YSBpcyBhIGJpdCBtb3JlIHRyaWNreS4gTXkgd2hpY2goKSBmdW5jdGlvbiBuZWVkcyBsb2dpYyB0byBkZXRlcm1pbmUgd2hpY2ggc2FtcGxlcyBhcmUgYm90aCBtdXRhbnQgYW5kIHRyZWF0ZWQgYW5kIHNhbXBsZXMgdGhhdCBhcmUgV1QgYW5kIHVudHJlYXRlZC4gSW4gb3JkZXIgdG8gZG8gdGhpcyBJIGNyZWF0ZWQgdHdvIHZlY3RvcnMsIG9uZSBzZWxlY3RpbmcgbXV0YW50IHRyZWF0ZWQgc2FtcGxlcyBhbmQgb25lIGNvbnRhaW5pbmcgV1QgdW50cmVhdGVkIHNhbXBsZXMuIFRoaXMgd2FzIGRvbmUgdXNpbmcgdGhlIGFuZCAoJikgYW5kIG9yICh8KSBsb2dpY2FsIG9wZXJhdG9ycy4gCmBgYHtyfQojUmV0cmlldmUgY291bnRzIGZvciBtdXRhbnQgdHJlYXRlZCBhbmQgd2lsZHR5cGUgdW50cmVhdGVkIHNhbXBsZXMKZGRzX211dHJlYXRlZHd0ID0gZGRzWyx3aGljaChjKGRkcyRHZW5vdHlwZSA9PSAiTVVUIiAmIGRkcyRUcmVhdG1lbnQgPT0gJ3RyZWF0ZWQnKSB8IGMoZGRzJEdlbm90eXBlID09ICdXVCcgJiBkZHMkVHJlYXRtZW50ID09ICd1bnRyZWF0ZWQnKSldCgojU2V0IHRoZSBkZXNpZ24gdG8gY29tcGFyZSBleHByZXNzaW9uIGJldHdlZW4gdHJlYXRtZW50cwpkZXNpZ24oZGRzX211dHJlYXRlZHd0KSA9IH5UcmVhdG1lbnQKCiNVc2UgREVTZXEyIHRvIGFuYWx5c2UgZGF0YQpkZV9tdXRyZWF0ZWR3dCA9IERFU2VxKGRkc19tdXRyZWF0ZWR3dCkKCiNTdG9yZSByZXN1bHRzCm11dHRyZWF0ZWR3dF9yZXN1bHRzID0gcmVzdWx0cyhkZV9tdXRyZWF0ZWR3dCwgYygnVHJlYXRtZW50JywndHJlYXRlZCcsJ3VudHJlYXRlZCcpKQpgYGAKIyMjIFdUIHRyZWF0ZWQgdnMgV1QgdW5udHJlYXRlZApUaGlzIGlzIGp1c3QgYSBzaW1wbGUgY2FzZSBvZiBzZXBlcmF0aW5nIHRoZSBXVCBkYXRhIGludG8gYSBzdWJzZXQgYXMgaSBkaWQgYmVmb3JlIHdpdGggdGhlIG11dGFudCBzYW1wbGVzCmBgYHtyfQojUmV0cmlldmUgY291bnRzIGZvciBtdXRhbnQgc2FtcGxlcwpkZHNfd3QgPSBkZHNbLHdoaWNoKGRkcyRHZW5vdHlwZSA9PSAiV1QiKV0KCiNTZXQgdGhlIGRlc2lnbiB0byBjb21wYXJlIGV4cHJlc3Npb24gYmV0d2VlbiB0cmVhdG1lbnRzCmRlc2lnbihkZHNfd3QpID0gflRyZWF0bWVudAoKI1VzZSBERVNlcTIgdG8gYW5hbHlzZSBkYXRhCmRlX3d0ID0gREVTZXEoZGRzX3d0KQoKI1N0b3JlIHJlc3VsdHMKd3RfcmVzdWx0cyA9IHJlc3VsdHMoZGVfd3QsIGNvbnRyYXN0ID0gYygnVHJlYXRtZW50JywndHJlYXRlZCcsJ3VudHJlYXRlZCcpKQpgYGAKTm93IHRoYXQgSSd2ZSBzdWJzZXR0ZWQgdGhlIGRhdGEgaSBjYW4gbW92ZSBvbiB0byB2aXN1YWxpc2F0aW9uLCB3aGljaCBpIHdpbGwgZG8gYW5vdGhlciBkYXkuCgojIDI4LzEwLzIwMjAgUHJvY2Vzc2luZyByZXN1bHRzIGZvciB2aXN1YWxpc2F0aW9uCk5vdyB0aGF0IGl2ZSBnZW5lcmF0ZWQgbXkgcmVzdWx0cyB0aGVyZXMgYSBmZXcgdGhpbmdzIEkgbmVlZCB0byBkbyBiZWZvcmUgZ3JhcGhpbmcgdGhlbS4gRmlyc3QgSSBuZWVkIHRvIGFzc2lnbiBleHRlcm5hbCBnZW5lIG5hbWVzIHRvIG15IHJlc3VsdHMgdG8gbWFrZSBkaWZmZXJlbnRhaWxseSBleHByZXNzZWQgZ2VuZXMgZWFzaWx5IGlkZW50aWZpYWJsZSBieSB0aGVpciBuYW1lIGFzIG9wcG9zZWQgdG8gYSBsb25nIGVuc2VtYmwgaWQsIHdoaWNoIG1ha2VzIGl0IGVhc2llciB0byBsYWJlbCB0aGVtIChhbmQgZ29vZ2xlIHRoZW0pLgoKSW4gb3JkZXIgdG8gYWRkIGdlbmUgc3ltYm9scyBJIG5lZWQgYSBkYXRhYmFzZSBjb250YWludGluZyBnZW5lIHN5bWJvbHMgbWF0Y2hlZCB0byBlbnNlbWJsIGlkcy4gRm9yIHRoaXMgaSB1c2VkIHRoZSBiaW9tYXJ0IHBhY2thZ2UsIHdoaWNoIGlzIGEgbGlicmFyeSBvZiBhbGwgZ2VuZSBuYW1lcyBtYXRjaGVkIHRvIGVuc2VtYmwgaWQgZm9yIG1hbnkgZGlmZmVyZW50IG9yZ2Fuc2ltcy4gVGhlIGdlbmUgc3ltYm9scyB3aWxsIG5lZWQgdG8gYmUgbWF0Y2hlZCB0byB0aGUgZW5zZW1ibCBpZHMgaW4gbXkgcmVzdWx0cyBhbmQgam9pbmVkIHRvIGVhY2ggcmVzdWx0cyB0YWJsZS4gCgpGaXJzdCBpIHdpbGwgcmV0cmlldmUgdGhlIGdlbmUgc3ltYm9scyBmcm9tIGJpb21hUnQ6CmBgYHtyfQojSW5pdGlhbGlzZSBkYXRhYmFzZSB3aXRoIGdlbmUgc3ltYm9scwpsaWJyYXJ5KGJpb21hUnQpCgojcmV0cmlldmUgZGF0YSBmb3IgemVicmFmaXNoCmVuc2VtYmwgPSB1c2VNYXJ0KCJlbnNlbWJsIixkYXRhc2V0PSJkcmVyaW9fZ2VuZV9lbnNlbWJsIikKYGBgCgpFYWNoIG9mIG15IHJlc3VsdHMgb2JqZWN0cyBkb2VzIG5vdCBjb250YWluIGEgY29sdW1uIGZvciBlbnNlbWJsIGlkLiBpbnN0ZWFkIHRoZSBlbnNlbWJsIGlkIG9mIGVhY2ggZ2VuZSBpcyBhIHJvdyBuYW1lLiBUaGlzIGlzIGEgcHJvYmxlbSBhcyBpIHdvbnQgYmUgYWJsZSB0byBlYXNpbHkgc2VsZWN0IHRoZSBlbnNlbWJsIGlkcyBvZiBlYWNoIGdlbmUgdG8gbWF0Y2ggd2l0aCB0aG9zZSBpbiB0aGUgZXh0ZXJuYWwgZGF0YWJhc2UuIEkgd2lsbCBoYXZlIHRvIHRoZXJlZm9yIGFzc2lnbiBhIG5ldyBjb2x1bW4gdG8gZWFjaCBvZiBteSByZXN1bHRzIHRhYmxlcyBjb250YWluaW5nIHRoZSBlbnNlbWJsIGlkcyBvZiB0aGUgZ2VuZXMuIEkgZGlkIHRoaXMgdXNpbmcgdGhlIHNhcHBseSBmdW5jdGlvbiB0byBjcmVhdGUgYSBuZXcgY29sdW1uIG5hbWVkICJlbnNlbWJsIiB0aGF0IGNvbnRhaW5lZCB0aGUgcm93bmFtZXMgb2YgdGhlIHRhYmxlIGFuZCB0aGVyZWZvciB0aGUgZW5zZW1ibCBpZHMgb2YgZWFjaCBnZW5lLgoKYGBge3J9CiNDcmVhdGUgbmV3IGNvbHVtbnMgZm9yIGVuc21ibCBpZCBpbiBlYWNoIHJlc3VsdHMgdGFibGUKZ2Vub3R5cGVfcmVzdWx0cyRlbnNlbWJsIDwtIHNhcHBseSggc3Ryc3BsaXQoIHJvd25hbWVzKGdlbm90eXBlX3Jlc3VsdHMpLCBzcGxpdD0iXFwrIiApLCAiWyIsIDEgKQptdXRyZWF0bWVudF9yZXN1bHRzJGVuc2VtYmwgPC0gc2FwcGx5KCBzdHJzcGxpdCggcm93bmFtZXMobXV0cmVhdG1lbnRfcmVzdWx0cyksIHNwbGl0PSJcXCsiICksICJbIiwgMSApCm11dHRyZWF0ZWR3dF9yZXN1bHRzJGVuc2VtYmwgPC0gc2FwcGx5KCBzdHJzcGxpdCggcm93bmFtZXMobXV0dHJlYXRlZHd0X3Jlc3VsdHMpLCBzcGxpdD0iXFwrIiApLCAiWyIsIDEgKQp3dF9yZXN1bHRzJGVuc2VtYmwgPC0gc2FwcGx5KCBzdHJzcGxpdCggcm93bmFtZXMod3RfcmVzdWx0cyksIHNwbGl0PSJcXCsiICksICJbIiwgMSApCmBgYAoKCgpBbGwgdGhlIGdlbmUgc3ltYm9scyBhbmQgZW5zZW1ibCBpZHMgYXJlIHN0b3JlZCBpbiB0aGUgZW5zZW1ibCBvYmplY3QuIEluIG9yZGVyIHRvIG1hdGNoIHRoZXNlIHRvIG15IHJlc3VsdHMgSSBuZWVkIHRvIGNyZWF0ZSBhIGdlbmVtYXAgb2JqZWN0IHRoYXQgcmV0cmlldmVzIHRoZSBlbnNlbWJsIGlkIGFuZCBleHRlcm5hbCBnZW5lIG5hbWVzIHRoYXQgbWF0Y2ggd2l0aCB0aGUgZW5zZW1ibCBpZHMgaW4gbXkgcmVzdWx0cy4gc2luY2UgYWxsIHN1YnNldHMgdGVzdGVkIGZvciB0aGUgc2FtZSBnZW5lcyBpIGNhbiB1c2UgYW55IG9mIHRoZW0gdG8gbWF0Y2ggdGhlIGVtc21ibCBpZHMgYW5kIGNyZWF0ZSB0aGUgZ2VuZSBtYXAuCgpgYGB7cn0KI0dlbmVyYXRlIGdlbmVtYXAgd2l0aCBlbnNlbWJsIGlkcyBhbmQgZXh0ZXJuYWwgZ2VuZSBuYW1lcy4KZ2VuZW1hcCA9IGdldEJNIChhdHRyaWJ1dGVzID0gYygiZW5zZW1ibF9nZW5lX2lkIiwiZXh0ZXJuYWxfZ2VuZV9uYW1lIiksCiAgICAgICAgICAgICAgICAgZmlsdGVycyA9ICJlbnNlbWJsX2dlbmVfaWQiLAogICAgICAgICAgICAgICAgIHZhbHVlcyA9IHd0X3Jlc3VsdHMkZW5zZW1ibCwKICAgICAgICAgICAgICAgICBtYXJ0ID0gZW5zZW1ibCkKCmBgYAoKClRoZSBnZW5lbWFwIG9iamVjdCBub3cgY29udGFpbnMgYSB0YWJsZSB3aXRoIHRoZSBlbnNlbWJsIGlkIGZyb20gbXkgcmVzdWx0cyBhbmQgdGhlIGNvcnJvc3BvbmRpbmcgZXh0ZXJuYWwgZ2VuZSBpZCBmcm9tIHRoZSBiaW9NYXJ0IGRhdGFiYXNlLiBJIG5vdyBuZWVkIHRvIGpvaW4gdGhpcyB0byBteSBvcmlnaW5hbCByZXN1bHRzIHRhYmxlcyBpbmRpdmlkdWFsbHkuCmBgYHtyfQojTWF0Y2ggZ2VuZSBzeW1ib2xzIHdpdGggZW5zZW1ibCBpZHMgZnJvbSByZXN1bHRzCmlkeCA9IG1hdGNoKHd0X3Jlc3VsdHMkZW5zZW1ibCwgZ2VuZW1hcCRlbnNlbWJsX2dlbmVfaWQpCgojSm9pbiB0aGUgZ2VuZSBpZCB0YWJsZSB0byBlYWNoIG9mIG15IHJlc3VsdHMgdGFibGVzCnd0X3Jlc3VsdHMkZXh0ZXJuYWxfZ2VuZV9uYW1lID0gZ2VuZW1hcCRleHRlcm5hbF9nZW5lX25hbWVbaWR4XSAKZ2Vub3R5cGVfcmVzdWx0cyRleHRlcm5hbF9nZW5lX25hbWUgPSBnZW5lbWFwJGV4dGVybmFsX2dlbmVfbmFtZVtpZHhdCm11dHJlYXRtZW50X3Jlc3VsdHMkZXh0ZXJuYWxfZ2VuZV9uYW1lID0gZ2VuZW1hcCRleHRlcm5hbF9nZW5lX25hbWVbaWR4XQptdXR0cmVhdGVkd3RfcmVzdWx0cyRleHRlcm5hbF9nZW5lX25hbWUgPSBnZW5lbWFwJGV4dGVybmFsX2dlbmVfbmFtZVtpZHhdCmBgYAoKTm93IHRoYXQgSSBoYXZlIG15IHJlc3VsdHMgZm9yIGVhY2ggcGFpcndpc2UgY29tcGFyaXNvbiBJIGNhbiBzYXZlIHRoZW0gdG8gY3N2IGZpbGVzIHRvIHN0b3JlIHRoZSBkYXRhIGFuZCBtYWtlIHN1cmUgSSBkb250IGhhdmUgdG8gcnVuIGFsbCBvZiB0aGUgYWJvdmUgY29kZSBhZ2FpbiBpbiB0aGUgZnV0dXJlLiBJbnN0ZWFkIGkgY2FuIHNpbXBseSByZWFkIHRoZSBkYXRhIGZyb20gdGhlc2UgZmlsZXMgd2hlbmV2ZXIgaSBuZWVkIGl0LiBGdXJ0aGVybW9yZSBpdCBtZWFucyBpIGhhdmUgYSBwZXJtYW5hbnQgY29weSBvZiBteSByZXN1bHRzLCByZWR1Y2luZyB0aGUgY2hhbmNlcyBvZiBtZSBsb3NpbmcgdGhlbS4KCkluIG9yZGVyIHRvIGNvbnZlcnQgdGhlIGRhdGEgdG8gYSBjc3YgZmlsZSBpIGNhbiB1c2UgdGhlIHJlYWRyIHdyaXRlLmNzdigpIGZ1bmN0aW9uLiBNeSBkYXRhIGhhcyB0byBiZSBpbiB0aGUgZm9ybSBvZiBhIGRhdGEgZnJhbWUgaW4gb3JkZXIgdG8gZG8gdGhpcyBzbyBJIGNvbnZlcnRlZCBpdCB1c2luZyBhcy5kYXRhLmZyYW1lKCkuIEkgYWxzbyBhcnJhbmdlZCB0aGUgZGF0YSBieSBwYWRqIGluIG9yZGVyIHRvIHNlZSB3aGljaCByZXN1bHRzIHdoZXJlIHRoZSBtb3N0IHNpZ25pZmljYW50LiAKClRoZSBkaXJlY3RvcmllcyB1c2VkIHRvIHN0b3JlIHRoZSByZXN1bHRzIGNhbiBiZSBzZWVuIGluIHRoZSBjb2RlIGJlbG93LgpgYGB7cn0KbGlicmFyeShkcGx5cikKI1dyaXRlIHd0IHJlc3VsdHMgdG8gYSBmaWxlIAp3cml0ZS5jc3YoYXJyYW5nZShhcy5kYXRhLmZyYW1lKHd0X3Jlc3VsdHMpLCBwYWRqKSxmaWxlID0gIlJlc3VsdHMvd3RfcmVzdWx0cy5jc3YiKQoKI1dyaXRlIGdlbm90eXBlIHJlc3VsdHMgdG8gYSBmaWxlIAp3cml0ZS5jc3YoYXJyYW5nZShhcy5kYXRhLmZyYW1lKGdlbm90eXBlX3Jlc3VsdHMpLCBwYWRqKSxmaWxlID0gIlJlc3VsdHMvZ2Vub3R5cGVfcmVzdWx0cy5jc3YiKQoKI1dyaXRlIHRoZSBtdXRhdGVkIHRyZWF0bWVudCByZXN1bHRzIHRvIGEgZmlsZQp3cml0ZS5jc3YoYXJyYW5nZShhcy5kYXRhLmZyYW1lKG11dHJlYXRtZW50X3Jlc3VsdHMpLCBwYWRqKSxmaWxlID0gIlJlc3VsdHMvTXV0YW50X3RyZWF0bWVudF9yZXN1bHRzLmNzdiIpCgojV3JpdGUgdGhlIG11dGFudCB0cmVhdGVkIHZzIHd0IHJlc3VsdHMgdG8gYSBmaWxlCndyaXRlLmNzdihhcnJhbmdlKGFzLmRhdGEuZnJhbWUobXV0dHJlYXRlZHd0X3Jlc3VsdHMpLCBwYWRqKSxmaWxlID0gIlJlc3VsdHMvTXV0YW50X3RyZWF0ZWRfdnNfd3RfcmVzdWx0cy5jc3YiKQpgYGAKCgojIDI5LzEwLzIwMjAgVmlzdWFsaXNpbmcgdGhlIGRhdGEKTm93IGkgbmVlZCB0byB2aXN1YWxpc2UgdGhlIGRhdGEgZm9yIGVhY2ggb2YgbXkgcGFpcndpc2UgYW5hbHlzaXMKCiMgMjkvMTAvMjAyMCBNdXRhbnQgdW50cmVhdGVkIHZzIHdpbGR0eXBlIHVudHJlYXRlZCBzYW1wbGVzCkZpcnN0IGkgbmVlZCB0byBzaHJpbmsgdGhlIGxvZyBmb2xkIGNoYW5nZXMgb2YgbXkgcmVzdWx0cyBpbiBvcmRlciB0byBwcm9wZXJseSB2aXN1YWxpemVzIHRoZSBkYXRhIHdpdGhvdXQgYW55IGV4dHJlbWUgdmFsdWVzIGludGVyZmVyaW5nLiBJbiBvcmRlciB0byBkbyB0aGlzIGkgd2lsbCB1c2UgdGhlIGRlc2VxMiBsZmNzaHJpbmsgZnVuY3Rpb24uCgpgYGB7cn0KI1NocmluayB0aGUgbG9nIGZvbGQgY2hhbmdlcwpzaHJpbmtfZ2Vub3R5cGUgPSBsZmNTaHJpbmsoZGVfZ2Vub3R5cGUsIGNvbnRyYXN0ID0gYygnR2Vub3R5cGUnLCdNVVQnLCdXVCcpLCByZXMgPSBnZW5vdHlwZV9yZXN1bHRzLCB0eXBlID0gJ25vcm1hbCcpCmBgYApJbiBvcmRlciB0byBnYWluIGFuIG92ZXJ2aWV3IG9mIG15IGRhdGEgaSBjYW4gZ2VuZXJhdGUgYW4gbWEgcGxvdC4gVGhpcyBnaXZlcyBhbiBvdmVydmlldyBvZiB0aGUgZGlzdHJ2dXRpb24gb2YgbXkgZGF0YSwgaS5lIHdoZXRoZXIgdGhlcmUgaXMgbW9yZSBvdmVyYWxsIHVwcmVndWxhdGlvbiBvciBkb3ducmVndWxhdGlvbiBvZiBnZW5lcy4KCiMjIyBNYSBwbG90IG9mIG11dGFudCB2cyB3aWxkdHlwZQpgYGB7cn0Kc2lnX2dlbm90eXBlID0gc3Vic2V0KGdlbm90eXBlX3Jlc3VsdHMsIHBhZGogPCAwLjA1KQoKcGxvdE1BKHNpZ19nZW5vdHlwZSx5bGltID0gYygtMTAsMTApKQpgYGAKVGhlIE1hIHBsb3QgZ2l2ZXMgbWUgYW4gb3ZlcnZpZXcgb2YgdGhlIGRpZmZlcmVudGlhbCBleHByZXNzaW9uLiB0aGUgbWEgcGxvdCBzaG93cyB0aGF0IG1vcmUgZ2VuZXMgd2hlcmUgRG93bnJlZ3VsYXRlZCBpbiB0aGUgd2lsZHR5cGUgY29tcGFyZWQgdG8gdGhlIG11dGFudHMKCk5leHQgSSBjcmVhdGVkIGEgdm9sY2FubyBwbG90IHdoaWNoIHBsb3RzIHRoZSBsb2cgZm9sZCBjaGFuZ2UgYWdhaW5zdCB0aGUgcCB2YWx1ZSBvZiBlYWNoIGdlbmUuIEdlbmVzIHdpdGggYSBwdmFsdWUgb2YgbGVzcyB0aGFuIDAuMDUgYW5kIGEgZm9sZCBjaGFuZ2UgZ3JlYXRlciB0aGFuICsxIG9yIC0xIGFyZSBoaWdobGlnaGh0ZWQgaW4gcmVkLiBJIHNldCB0aGUgY29kZSB0byBsYWJlbCB0aGUgdG9wIDMwIG1vc3Qgc2lnbmlmaWNhbnQgZ2VuZXMgd2hlcmUgcG9zc2libGUsIGhvd2V2ZXIgc29tZSBvZiB0aGUgZGF0YXBvaW50cyBhcmUgc28gY2xvc2UgdGhhdCBhIGRpc3RpbmN0IGxhYmVsIGNhbm5vdCBiZSBhcHBsaWVkLiBPbmNlIGFnYWluIGkgcmVzaXplZCB0aGUgZmlndXJlIHVzaW5nIHRoZSBjaHVuayBzZXR0aW5ncy4KCiMjIyBWb2xjYW5vIHBsb3Qgb2YgbXV0YW50IHZzIHdpbGR0eXBlCgpgYGB7ciBmaWcuaGVpZ2h0PTEwLGZpZy53aWR0aD0xNX0Kc2hyaW5rX2dlbm90eXBlID0gYXJyYW5nZShhcy5kYXRhLmZyYW1lKHNocmlua19nZW5vdHlwZSkscGFkaikKc3ltYiA9IHNocmlua19nZW5vdHlwZSRleHRlcm5hbF9nZW5lX25hbWVbMTozMF0KbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCkVuaGFuY2VkVm9sY2FubyhzaHJpbmtfZ2Vub3R5cGUsCiAgICAgICAgICAgICAgICBsYWIgPSBzaHJpbmtfZ2Vub3R5cGUkZXh0ZXJuYWxfZ2VuZV9uYW1lLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYyhzeW1iKSwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA5LjAsCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSA3LjAsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJDWVAyMUEyIE1VVCB2cyBXVCIsCiAgICAgICAgICAgICAgICBheGlzTGFiU2l6ZSA9IDM1LAogICAgICAgICAgICAgICAgdGl0bGVMYWJTaXplID0gNTAsCiAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICIgIiwKICAgICAgICAgICAgICAgIHggPSdsb2cyRm9sZENoYW5nZScsCiAgICAgICAgICAgICAgICB5ID0ncGFkaicsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJlbHM9YygnTm90IHNpZy4nLCdMb2cgKGJhc2UgMikgRkMnLCdwLXZhbHVlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC12YWx1ZSAmIExvZyAoYmFzZSAyKSBGQycpLAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDIwLAogICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSAxMCkKYGBgClRoZSBwbG90IHNob3dzIHRoYXQgbW9yZSBnZW5lcyB3aGVyZSBkb3ducmVndWxhdGVkIGluIHRoZSBtdXRhbnQgY29tcGFyZWQgdG8gdXByZWd1bGF0ZWQuIFRoZSBnZW5lIGZrYnA1IGlzIGNsZWFybHkgdGhlIG1vc3QgZG93bnJlZ3VsYXRlZCBnZW5lIGFuZCBzaG93cyB0aGUgaGlnaGVzdCBzdGF0aXN0aWNhbCBzaWduaWZpY2FuY2UuIFBhaWNzIHdhcyB0aGUgbW9zdCBzaWduaWZpY2FudCB1cHJlZ3VsYXRlZCBnZW5lIGluIHRoZSBtdXRhbnRzLgoKSSBjYW4gYWxzbyBjcmVhdGUgYSBoZWF0bWFwIGJhc2VkIG9uIHRoZSByZWFkIGRhdGEgZm9yIGVhY2ggZ2VuZSBpbiBvcmRlciB0byBnaXZlIGEgY2xvc2VyIGxvb2sgYXQgdGhlIGRpZmZlcmVuY2VzIGJldHdlZW4gZXhwcmVzc2lvbi4gSSBjcmVhdGVkIGEgbWF0cml4IGNvbnRhaW5pbmcgdGhlIHRvcCAzMCBtb3N0IHNpZ25pZmljYW50bHkgZXhwcmVzc2VkIGdlbmVzIHdoaWNoIEkgdGhlbiBjcmVhdGVkIHRoZSBoZWF0bWFwIGZyb20uIEkgdXNlZCB0aGUgc2FtcGxlaW5mbyBvYmplY3QgdG8gbGFiZWwgdGhlIGdlbm90eXBlcyBvZiB0aGUgc2FtcGxlcyBhbmQgYW5ub3RhdGVkIGVhY2ggcm93IHdpdGggdGhlIGdlbmUgc3ltYm9scy4KCkkgdXNlZCB0aGUgc3ltYiB2YXJpYWJsZSBmcm9tIGVhcmxpZXIgdG8gbGFiZWwgZWFjaCByb3cgd2l0aCB0aGUgZ2VuZSBpZC4KCmBgYHtyfQojSW5pdGlhbGlzZSBwaGVhdG1hcCBpZiBub3QgZG9uZSBwcmV2aW91c2x5CmxpYnJhcnkocGhlYXRtYXApCgojbG9nMiB0cmFuc2Zvcm1hdGlvbgp2c2RfZ2Vub3R5cGUgPSB2c3QoZGRzX2dlbm90eXBlKQoKI0NyZWF0ZSBtYXRyaXggY29udGFpbmluZyB0aGUgdG9wIDMwIG1vc3Qgc2lnbmlmaWNhbnQgZ2VuZXMKZ2Vub3R5cGVfbWF0ID0gYXNzYXkodnNkX2dlbm90eXBlKVsgaGVhZChvcmRlcihnZW5vdHlwZV9yZXN1bHRzJHBhZGopLDMwKSwgXQoKI1N1YnRyYWN0IHRoZSBtZWFuIHJlYWRzIGZvciBlYWNoIGdlbmUgCmdlbm90eXBlX21hdCA9IGdlbm90eXBlX21hdCAtIHJvd01lYW5zKGdlbm90eXBlX21hdCkKCiNSZWFkIGluIGdlbm90eXBlcyBmb3IgYW5ub3RhdGlvbgpzYW1wbGVpbmZvID0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKGRkcylbYygnR2Vub3R5cGUnKV0pCgoKI1Bsb3QgaGVhdG1hcApwaGVhdG1hcChnZW5vdHlwZV9tYXQsIAogICAgICAgICBmb250c2l6ZSA9IDcsIAogICAgICAgICBjZWxsd2lkdGggPSAzMCwgCiAgICAgICAgIGNlbGxoZWlnaHQgPSA3LCAKICAgICAgICAgbGFiZWxzX3JvdyA9IHN5bWIsIAogICAgICAgICBhbm5vdGF0aW9uID0gc2FtcGxlaW5mbywgCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IEYsIAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSBGLAogICAgICAgICBsYWJlbHNfY29sID0gZGRzX2dlbm90eXBlJE5hbWUpCmBgYApUaGUgaGVhdG1hcCBwcm92aWRlcyBtb3JlIGluc2lnaHQgaW50byB0aGUgcmVzdWx0cyBiZWhpbmQgdGhlIHZvbGNhbm8gcGxvdC4gSXQgc2hvd3MgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlIGJldHdlZW4gcmVhZHMgZm9yIGZrYnA1IGluIHRoZSBXVCBhbmQgTXV0IHNhbXBsZXMuIE9mIHRoZSB0b3AgMzAgZ2VuZXMgb25seSA0IHdoZXJlIHVwcmVndWxhdGVkIGluIHRoZSBtdXRhbnRzLCB0aGUgcmVzdCBhbGwgc2hvdyBxdWl0ZSBzIHNpZ25pZmljYW50IGRvd25yZWd1bGF0aW9uLgoKTm93IHRoYXQgSSBoYXZlIGEgYmFzaWMgc2V0IG9mIGdyYXBocyBpIGNhbiByZXBlYXQgdGhpcyBwcm9jZXNzIGZvciB0aGUgb3RoZXIgY29tcGFyaXNvbnMuCgojIDAxLzExLzIwMjAgTXV0YW50IHRyZWF0ZWQgdnMgdW50cmVhdGVkCgojIyMgTWEgcGxvdCBvZiBtdXRhbnQgdHJlYXRlZCB2cyB1bnRyZWF0ZWQKVGhlIE1hIHBsb3Qgc2hvd3MgdHJlYXRlZCB2cyB1bnRyZWF0ZWQgbXV0YW50IHNhbXBsZXMuIHRob3NlIHdpdGggYSBuZWdhdGl2ZSBmb2xkIGNoYW5nZSBhcmUgdW5kZXJleHByZXNzZWQgaW4gdGhlIHRyZWF0ZWQgZ3JvdXAgYW5kIHRob3NlIHdpdGggYSBwb3NpdGl2ZSBmb2xkIGNoYW5nZSB3aGVyZSB1cHJlZ3VsdGVkIGluIHRoZSB0cmVhdGVkIGdyb3VwLiBUaGUgcGxvdCBzaG93cyB0aGF0IG1vcmUgZ2VuZXMgd2hlcmUgdXByZWd1bGF0ZWQgdGhhbiBkb3ducmVndWxhdGVkIGluIHRoZSB0cmVhdGVkIGdyb3VwLgpgYGB7cn0KI1N1YnNldCB0b3AgMzAgbW9zdCBzaWcgcmVzdWx0cwpzaWdfbXV0dHJlYXRtZW50ID0gc3Vic2V0KG11dHJlYXRtZW50X3Jlc3VsdHMsIHBhZGogPCAwLjA1KQoKI2NyZWF0ZSBwbG90IApwbG90TUEoc2lnX211dHRyZWF0bWVudCwgeWxpbSA9IGMoLTEwLCAxMCkpCmBgYApOZXh0IGkgcHJvZHVjZWQgYSB2b2xhbm8gcGxvdC4KQXMgYmVmb3JlIGkgcGVyZm9ybWVkIGFuIGxmYyBzaHJpbmsgb24gdGhlIGRhdGEgCmBgYHtyfQojU2hyaW5rIGxmYwpzaHJpbmtfbXV0dHJlYXRtZW50ID0gbGZjU2hyaW5rKGRlX211dHRyZWF0bWVudCwgY29udHJhc3QgPSBjKCdUcmVhdG1lbnQnLCd0cmVhdGVkJywndW50cmVhdGVkJyksIHJlcyA9IG11dHJlYXRtZW50X3Jlc3VsdHMsIHR5cGUgPSAnbm9ybWFsJykKYGBgCkkgY3JlYXRlZCB0aGUgdm9sY2FubyBwbG90IGFzIHByZXZpb3VzbHkgZGVzY3JpYmVkLCBleGNlcHQgdGhpcyB0aW1lIHVzaW5nIHRoZSBtdXR0cmVhdG1lbnQgZGF0YXNldC4KCmBgYHtyIGZpZy5oZWlnaHQ9MTIsZmlnLndpZHRoPTE1fQojQXJyYW5nZSBieSBwIHZhbHVlCnNocmlua19tdXR0cmVhdG1lbnQgPSBhcnJhbmdlKGFzLmRhdGEuZnJhbWUoc2hyaW5rX211dHRyZWF0bWVudCkscGFkaikKCiNSZXRyaWV2ZSBzeW1ib2xzIG9mIHRvcCAzMCBnZW5lcwpzeW1iID0gc2hyaW5rX211dHRyZWF0bWVudCRleHRlcm5hbF9nZW5lX25hbWVbMTozMF0KCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQoKI0NyZWF0ZSBwbG90CkVuaGFuY2VkVm9sY2FubyhzaHJpbmtfbXV0dHJlYXRtZW50LAogICAgICAgICAgICAgICAgbGFiID0gc2hyaW5rX211dHRyZWF0bWVudCRleHRlcm5hbF9nZW5lX25hbWUsCiAgICAgICAgICAgICAgICBsYWJTaXplID0gNy4wLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYyhzeW1iKSwKICAgICAgICAgICAgICAgIHBvaW50U2l6ZSA9IDUuMCwKICAgICAgICAgICAgICAgIHRpdGxlID0gIkNZUDIxQTIgTVVUIHRyZWF0ZWQgdnMgdW50cmVhdGVkIiwKICAgICAgICAgICAgICAgIGF4aXNMYWJTaXplID0gMzUsCiAgICAgICAgICAgICAgICB0aXRsZUxhYlNpemUgPSA1MCwKICAgICAgICAgICAgICAgIHN1YnRpdGxlID0gIiAiLAogICAgICAgICAgICAgICAgeCA9J2xvZzJGb2xkQ2hhbmdlJywKICAgICAgICAgICAgICAgIHkgPSdwYWRqJywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYmVscz1jKCdOb3Qgc2lnLicsJ0xvZyAoYmFzZSAyKSBGQycsJ3AtdmFsdWUnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdwLXZhbHVlICYgTG9nIChiYXNlIDIpIEZDJyksCiAgICAgICAgICAgICAgICBsZWdlbmRQb3NpdGlvbiA9ICdyaWdodCcsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJTaXplID0gMjAsCiAgICAgICAgICAgICAgICBsZWdlbmRJY29uU2l6ZSA9IDEwKQpgYGAKSW50ZXJlc3RpbmdseSB0aGUgcGxvdCBzaG93cyBhbiBhbG1vc3QgY29tcGxldGUgcmV2ZXJzYWwgaW4gZ2VuZSBleHByZXNzaW9uLiBtb3N0IG5vdGljYWJpbGUgaXMgdGhlIGNoYW5nZSBpbiBma2JwNSB3aGljaCBpcyBzaW5naWNhbnRseSB1cHJlZ3VsYXRlZCBpbiB0aGUgdHJlYXRlZCBncm91cC4KCkkgdGhlbiBjcmVhdGVkIGEgaGVhdG1hcCBhcyBkZXNjcmliZWQgYmVmb3JlIAoKYGBge3J9CiNJbml0aWFsaXNlIHBoZWF0bWFwIGlmIG5vdCBkb25lIHByZXZpb3VzbHkKbGlicmFyeShwaGVhdG1hcCkKCiNsb2cyIHRyYW5zZm9ybWF0aW9uCnZzZF9tdXR0cmVhdGVkID0gdnN0KGRkc19tdXR0cmVhdG1lbnQpCgojQ3JlYXRlIG1hdHJpeCBjb250YWluaW5nIHRoZSB0b3AgMzAgbW9zdCBzaWduaWZpY2FudCBnZW5lcwptdXR0cmVhdGVkX21hdCA9IGFzc2F5KHZzZF9tdXR0cmVhdGVkKVsgaGVhZChvcmRlcihtdXRyZWF0bWVudF9yZXN1bHRzJHBhZGopLDMwKSwgXQoKI1N1YnRyYWN0IHRoZSBtZWFuIHJlYWRzIGZvciBlYWNoIGdlbmUgCm11dHRyZWF0ZWRfbWF0ID0gbXV0dHJlYXRlZF9tYXQgLSByb3dNZWFucyhtdXR0cmVhdGVkX21hdCkKCiNSZWFkIGluIGdlbm90eXBlcyBmb3IgYW5ub3RhdGlvbgpzYW1wbGVpbmZvID0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKGRkc19tdXR0cmVhdG1lbnQpWydUcmVhdG1lbnQnXSkKCgoKI1Bsb3QgaGVhdG1hcApwaGVhdG1hcChtdXR0cmVhdGVkX21hdCwgCiAgICAgICAgIGZvbnRzaXplID0gNywgCiAgICAgICAgIGNlbGx3aWR0aCA9IDMwLCAKICAgICAgICAgY2VsbGhlaWdodCA9IDcsIAogICAgICAgICBsYWJlbHNfcm93ID0gc3ltYiwgCiAgICAgICAgIGFubm90YXRpb24gPSBzYW1wbGVpbmZvLCAKICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRiwgCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9IEYsCiAgICAgICAgIGxhYmVsc19jb2wgPSBkZHNfbXV0dHJlYXRtZW50JE5hbWUpCmBgYApPbmNlIGFnYWluIGl0IGFwcGVhcnMgdGhhdCB0aGUgZXhwcmVzc2lvbiBpcyB0aGUgb3Bwb3NpdGUgd2hlbiB0aGUgbXV0YW50cyBhcmUgdHJlYXRlZC4gT25seSBvbmUgZ2VuZSB3YXMgZG93bnJlZ3VsYXRlZCwgd2hpbHN0IGFsbCB0aGUgcmVhdCBpbmxjdWRpbmcgZmticDUgd2hlcmUgc2lnbmlmaWNhbnRseSB1cHJlZ3VsYXRlZAoKIzAxLzExLzIwMjAgTXV0YW50IHRyZWF0ZWQgdnMgd2lsZCB0eXBlCiMjIyBNYSBwbG90IG9mIG11dGFudCB0cmVhdGVkIHZzIFdUIHVudHJlYXRlZApgYGB7cn0Kc2lnX211dHRyZWF0bWVudHd0ID0gc3Vic2V0KG11dHRyZWF0ZWR3dF9yZXN1bHRzLCBwYWRqIDwgMC4wNSkKCnBsb3RNQShzaWdfbXV0dHJlYXRtZW50d3QsIHlsaW0gPSBjKC0xMCwgMTApKQpgYGAKSW50ZXJlc3RpbmdseSB0aGlzIE1BIHBsb3Qgc2hvd3MgdGhlIGdyZWF0ZXN0IGRpZmZlcmVuY2UgaW4gZXhwcmVzc2lvbiBzbyBmYXIuIFRoZXJlIGFyZSBtb3JlIHNpZ25pZmljYW50IGdlbmVzIG9uIHRoaXMgcGxvdCB0aGFuIGluIHRoZSBwcmV2aW91cyB0d28gY29tcGFyaXNvbnMsIGRlc3BpdGUgdGhlIGZhY3QgdGhhdCBJIGVjcHJlY3RlZCB0aGUgdHJlYXRlZCBtdXRhbnRzIHRvIGhhdmUgYXQgbGVhc3Qgc29tZSBzaW1pbGFyaXR5IHRvIHRoZSB3aWxkIHR5cGVzLgoKCk5leHQgaSBwcm9kdWNlZCBhIHZvbGFubyBwbG90LgpBcyBiZWZvcmUgaSBwZXJmb3JtZWQgYW4gbGZjIHNocmluayBvbiB0aGUgZGF0YSAKCmBgYHtyfQpzaHJpbmtfbXV0dHJlYXRtZW50d3QgPSBsZmNTaHJpbmsoZGVfbXV0cmVhdGVkd3QsIGNvbnRyYXN0ID0gYygnVHJlYXRtZW50JywndHJlYXRlZCcsJ3VudHJlYXRlZCcpLCByZXMgPSBtdXR0cmVhdGVkd3RfcmVzdWx0cywgdHlwZSA9ICdub3JtYWwnKQpgYGAKSSBjcmVhdGVkIHRoZSB2b2xjYW5vIHBsb3QgYXMgcHJldmlvdXNseSBkZXNjcmliZWQsIGV4Y2VwdCB0aGlzIHRpbWUgdXNpbmcgdGhlIG11dHRyZWF0bWVudHd0IGRhdGFzZXQuCgpgYGB7ciBmaWcuaGVpZ2h0PTEyLGZpZy53aWR0aD0xNX0Kc2hyaW5rX211dHRyZWF0bWVudHd0ID0gYXJyYW5nZShhcy5kYXRhLmZyYW1lKHNocmlua19tdXR0cmVhdG1lbnR3dCkscGFkaikKc3ltYiA9IHNocmlua19tdXR0cmVhdG1lbnR3dCRleHRlcm5hbF9nZW5lX25hbWVbMTozMF0KbGlicmFyeShFbmhhbmNlZFZvbGNhbm8pCkVuaGFuY2VkVm9sY2FubyhzaHJpbmtfbXV0dHJlYXRtZW50d3QsCiAgICAgICAgICAgICAgICBsYWIgPSBzaHJpbmtfbXV0dHJlYXRtZW50d3QkZXh0ZXJuYWxfZ2VuZV9uYW1lLAogICAgICAgICAgICAgICAgc2VsZWN0TGFiID0gYyhzeW1iKSwKICAgICAgICAgICAgICAgIGxhYlNpemUgPSA5LjAsCiAgICAgICAgICAgICAgICBwb2ludFNpemUgPSA1LjAsCiAgICAgICAgICAgICAgICB0aXRsZSA9ICJDWVAyMUEyIE1VVCB0cmVhdGVkIHZzIFdUIHVudHJlYXRlZCIsCiAgICAgICAgICAgICAgICBheGlzTGFiU2l6ZSA9IDM1LAogICAgICAgICAgICAgICAgdGl0bGVMYWJTaXplID0gNTAsCiAgICAgICAgICAgICAgICBzdWJ0aXRsZSA9ICIgIiwKICAgICAgICAgICAgICAgIHggPSdsb2cyRm9sZENoYW5nZScsCiAgICAgICAgICAgICAgICB5ID0ncGFkaicsCiAgICAgICAgICAgICAgICBsZWdlbmRMYWJlbHM9YygnTm90IHNpZy4nLCdMb2cgKGJhc2UgMikgRkMnLCdwLXZhbHVlJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncC12YWx1ZSAmIExvZyAoYmFzZSAyKSBGQycpLAogICAgICAgICAgICAgICAgbGVnZW5kUG9zaXRpb24gPSAncmlnaHQnLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiU2l6ZSA9IDIwLAogICAgICAgICAgICAgICAgbGVnZW5kSWNvblNpemUgPSAxMCkKYGBgCk9uY2UgYWdhaW4gdGhpcyBwbG90IHNob3dzIHRoYXQgdGhlcmUgaXMgYSBzaWduaWZjYW50IGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZ2VuZSBleHByZXNzaW9uLCBob3dldmVyIHVubGlrZSB0aGUgcHJldmlvdXMgdHdvIGNvbXBhcmlzb25zIGl0IGlzbnQgc2tld2VkIGluIGFueSBkaXJlY3Rpb24uIFNpZ25pZmljYW5sdHkgZG93bnJlZ3VsYXRlZCBnZW5lcyBpbmNsdWRlIHNvbWUgaW52b2x2ZWQgaW4gaW1tdW5lIHJlZ3VsYXRpb24sIHN1Y2ggYXMgYW54YTEuIAoKSSB0aGVuIGNyZWF0ZWQgYSBoZWF0bWFwIGFzIGRlc2NyaWJlZCBiZWZvcmUgCgpgYGB7cn0KI0luaXRpYWxpc2UgcGhlYXRtYXAgaWYgbm90IGRvbmUgcHJldmlvdXNseQpsaWJyYXJ5KHBoZWF0bWFwKQoKI2xvZzIgdHJhbnNmb3JtYXRpb24KdnNkX211dHJlYXRlZHd0ID0gdnN0KGRkc19tdXRyZWF0ZWR3dCkKCiNDcmVhdGUgbWF0cml4IGNvbnRhaW5pbmcgdGhlIHRvcCAzMCBtb3N0IHNpZ25pZmljYW50IGdlbmVzCm11dHRyZWF0ZWR3dF9tYXQgPSBhc3NheSh2c2RfbXV0cmVhdGVkd3QpWyBoZWFkKG9yZGVyKG11dHRyZWF0ZWR3dF9yZXN1bHRzJHBhZGopLDMwKSwgXQoKI1N1YnRyYWN0IHRoZSBtZWFuIHJlYWRzIGZvciBlYWNoIGdlbmUgCm11dHRyZWF0ZWR3dF9tYXQgPSBtdXR0cmVhdGVkd3RfbWF0IC0gcm93TWVhbnMobXV0dHJlYXRlZHd0X21hdCkKCiNSZWFkIGluIGdlbm90eXBlcyBmb3IgYW5ub3RhdGlvbgpzYW1wbGVpbmZvID0gYXMuZGF0YS5mcmFtZShjb2xEYXRhKGRkc19tdXRyZWF0ZWR3dClbYygnR2Vub3R5cGUnLCdUcmVhdG1lbnQnKV0pCgoKCiNQbG90IGhlYXRtYXAKcGhlYXRtYXAobXV0dHJlYXRlZHd0X21hdCwgCiAgICAgICAgIGZvbnRzaXplID0gNywgCiAgICAgICAgIGNlbGx3aWR0aCA9IDMwLCAKICAgICAgICAgY2VsbGhlaWdodCA9IDcsIAogICAgICAgICBsYWJlbHNfcm93ID0gc3ltYiwgCiAgICAgICAgIGFubm90YXRpb24gPSBzYW1wbGVpbmZvLCAKICAgICAgICAgY2x1c3Rlcl9yb3dzID0gRiwgCiAgICAgICAgIGNsdXN0ZXJpbmdfZGlzdGFuY2Vfcm93cyA9IEYsCiAgICAgICAgIGxhYmVsc19jb2wgPSBkZHNfbXV0cmVhdGVkd3QkTmFtZSkKYGBgClRoZSBoZWF0bWFwIG1pcnJvcnMgd2hhdCB3YXMgc2VlbiBpbiB0aGUgdm9sY2FubyBwbG90LCBob3dldmVyIHdoZW4gY29tcGFyaW5nIHRoaXMgd2l0aCB0aGUgb3RoZXJzIGl0IGFwcGVhcnMgdGhhdCB0aGUgZGlmZmVyZW5jZSBpbiB0aGUgY291bnQgZGF0YSBpcyBub3QgYXMgcHJvbm91bmNlZCBhcyBpdCB3YXMgaW4gdGhlIHByZXZpb3VzIHR3byBjb21wYXJpc29ucy4gVGhpcyBtYXkgaW5kaWNhdGUgYSBsb3dlciBhbW91bnQgb2Ygb3ZlcmFsbCBkaWZmZXJlbmNlLCBpbXBseWluZyB0aGF0IGFsdGhvdWdoIHRoZXJlIGFyZSBkaWZmZXJlbmNlcywgdGhlc2UgYXJlIGxlc3MgcHJwbm91bmNlZCBhbmQgbWF5IGhhdmUgbGVzcyBvZiBhbiBlZmZlY3QuCgojMDMvMTEvMjAyMCBXaWxkIHR5cGUgdHJlYXRlZCB2cyB3aWxkIHR5cGUgdW50cmVhdGVkIAoKIyMjIE1hIHBsb3Qgb2Ygd2lsZCB0eXBlIHRyZWF0ZWQgdnMgdW50cmVhdGVkClRoZSBNYSBwbG90IHNob3dzIGV2ZW4gbW9yZSBkaWZmZXJlbmNlIGluIHRoaXMgY2FzZS4gSXQgYXBwZWFycyB0aGF0IGVsZXZhdGVkIGdsdWNvY29ydGljb2lkIHNpZ25hbGxpbmcgaGFzIGEgc2lnbmlmaWNhbnQgZWZmZWN0IG9uIGdlbmUgZXhwcmVzc2lvbi4KYGBge3J9CiNGaWx0ZXIgc2lnIGdlbmVzCnNpZ193dCA9IHN1YnNldCh3dF9yZXN1bHRzLCBwYWRqIDwgMC4wNSkKCiNQTG90IGRhdGEgCnBsb3RNQShzaWdfd3QsIHlsaW0gPSBjKC0xMCwgMTApKQpgYGAKTmV4dCBpIHByb2R1Y2VkIGEgdm9sYW5vIHBsb3QuCkFzIGJlZm9yZSBpIHBlcmZvcm1lZCBhbiBsZmMgc2hyaW5rIG9uIHRoZSBkYXRhIAoKYGBge3J9CiNsZmMgc2hyaW5rCnNocmlua193dCA9IGxmY1NocmluayhkZV93dCwgY29udHJhc3QgPSBjKCdUcmVhdG1lbnQnLCd0cmVhdGVkJywndW50cmVhdGVkJyksIHJlcyA9IHd0X3Jlc3VsdHMsIHR5cGUgPSAnbm9ybWFsJykKYGBgCkkgY3JlYXRlZCB0aGUgdm9sY2FubyBwbG90IGFzIHByZXZpb3VzbHkgZGVzY3JpYmVkLCBleGNlcHQgdGhpcyB0aW1lIHVzaW5nIHRoZSBtdXR0cmVhdG1lbnQgZGF0YXNldC4KCmBgYHtyIGZpZy5oZWlnaHQ9MTIsZmlnLndpZHRoPTE1fQojYXJyYW5nZSBieSBwIHZhbHVlCnNocmlua193dCA9IGFycmFuZ2UoYXMuZGF0YS5mcmFtZShzaHJpbmtfd3QpLHBhZGopCgojQ29sbGVjdCB0b3AgMzAgZ2VuZSBzeW1ib2xzCnN5bWIgPSBzaHJpbmtfd3QkZXh0ZXJuYWxfZ2VuZV9uYW1lWzE6MzBdCmxpYnJhcnkoRW5oYW5jZWRWb2xjYW5vKQoKI1Byb2R1Y2UgcGxvdApFbmhhbmNlZFZvbGNhbm8oc2hyaW5rX3d0LAogICAgICAgICAgICAgICAgbGFiID0gc2hyaW5rX3d0JGV4dGVybmFsX2dlbmVfbmFtZSwKICAgICAgICAgICAgICAgIHNlbGVjdExhYiA9IGMoc3ltYiksCiAgICAgICAgICAgICAgICBsYWJTaXplID0gNy4wLAogICAgICAgICAgICAgICAgcG9pbnRTaXplID0gNS4wLAogICAgICAgICAgICAgICAgdGl0bGUgPSAiV1QgdHJlYXRlZCB2cyB1bnRyZWF0ZWQiLAogICAgICAgICAgICAgICAgYXhpc0xhYlNpemUgPSAzNSwKICAgICAgICAgICAgICAgIHRpdGxlTGFiU2l6ZSA9IDUwLAogICAgICAgICAgICAgICAgc3VidGl0bGUgPSAiICIsCiAgICAgICAgICAgICAgICB4ID0nbG9nMkZvbGRDaGFuZ2UnLAogICAgICAgICAgICAgICAgeSA9J3BhZGonLAogICAgICAgICAgICAgICAgbGVnZW5kTGFiZWxzPWMoJ05vdCBzaWcuJywnTG9nIChiYXNlIDIpIEZDJywncC12YWx1ZScsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3AtdmFsdWUgJiBMb2cgKGJhc2UgMikgRkMnKSwKICAgICAgICAgICAgICAgIGxlZ2VuZFBvc2l0aW9uID0gJ3JpZ2h0JywKICAgICAgICAgICAgICAgIGxlZ2VuZExhYlNpemUgPSAyMCwKICAgICAgICAgICAgICAgIGxlZ2VuZEljb25TaXplID0gMTApCmBgYApTbGlnaHRseSBtb3JlIGdlbmVzIHdoZXJlIGRvd25yZWZ1bGF0ZWQgaW4gdGhlIHRyZWF0ZWQgZ3JvdXAgY29tcGFyZWQgdG8gdGhlIHVudHJlYXRlZC4gT25jZSBhZ2FpbiB0aGVzZSBnZW5lcyBhcHBlYXIgdG8gYmUgaW52b2x2ZWQgaW4gaW1tdW5lIHJlc3BvbnNlIHdpdGggYW5uZXhpbiBtYWtpbmcgYW4gYXBwZWFyYW5jZSBhZ2Fpbi4gQXMgYmVmb3JlIGhzYnA2IHdhcyBhbHNvIHVwcmVndWxhdGVkLiBUaGlzIG1heSBpbmRpY2F0ZSB0aGF0IHRyZWF0bWVudCB3aXRoIGh5ZHJvY29ydGlzb25lIHByb2R1Y2luZyBlZmZlY3RzIG9uIGdlbmUgZXhwcmVzc2lvbiB0aGF0IGFyZSBhc3NvY2lhdGVkIHdpdGggZWxldmF0ZWQgZ2x1Y29jb3J0aWNvaWQgc2lnbmFsbGluZy4gSXMgdGhlIHRyZWF0bWVudCB0aGVyZWZvciBhbiBvdmVya2lsbD8KCkkgdGhlbiBjcmVhdGVkIGEgaGVhdG1hcCBhcyBkZXNjcmliZWQgYmVmCgpgYGB7cn0KI0luaXRpYWxpc2UgcGhlYXRtYXAgaWYgbm90IGRvbmUgcHJldmlvdXNseQpsaWJyYXJ5KHBoZWF0bWFwKQoKI2xvZzIgdHJhbnNmb3JtYXRpb24KdnNkX3d0ID0gdnN0KGRkc193dCkKCiNDcmVhdGUgbWF0cml4IGNvbnRhaW5pbmcgdGhlIHRvcCAzMCBtb3N0IHNpZ25pZmljYW50IGdlbmVzCnd0X21hdCA9IGFzc2F5KHZzZF93dClbIGhlYWQob3JkZXIod3RfcmVzdWx0cyRwYWRqKSwzMCksIF0KCiNTdWJ0cmFjdCB0aGUgbWVhbiByZWFkcyBmb3IgZWFjaCBnZW5lIAp3dF9tYXQgPSB3dF9tYXQgLSByb3dNZWFucyh3dF9tYXQpCgojUmVhZCBpbiBnZW5vdHlwZXMgZm9yIGFubm90YXRpb24Kc2FtcGxlaW5mbyA9IGFzLmRhdGEuZnJhbWUoY29sRGF0YShkZHNfd3QpWydUcmVhdG1lbnQnXSkKCgoKI1Bsb3QgaGVhdG1hcApwaGVhdG1hcCh3dF9tYXQsIAogICAgICAgICBmb250c2l6ZSA9IDcsIAogICAgICAgICBjZWxsd2lkdGggPSAzMCwgCiAgICAgICAgIGNlbGxoZWlnaHQgPSA3LCAKICAgICAgICAgbGFiZWxzX3JvdyA9IHN5bWIsIAogICAgICAgICBhbm5vdGF0aW9uID0gc2FtcGxlaW5mbywgCiAgICAgICAgIGNsdXN0ZXJfcm93cyA9IEYsIAogICAgICAgICBjbHVzdGVyaW5nX2Rpc3RhbmNlX3Jvd3MgPSBGLAogICAgICAgICBsYWJlbHNfY29sID0gZGRzX3d0JE5hbWUpCmBgYApUaGUgaGVhdG1hcCBzaG93cyBzaWduaWZpY2FudCB1cHJlZ3VsYXRpb24gaW4gdGhlIHRvcCAzMCBnZW5lcy4gZ2VuZXMgb2Ygbm90ZSBhcmUgb25jZSBhZ2FpbiB0aGUgYW5uZXhpbiBnZW5lcywgd2hpYyBhcmUgaW52b2x2ZWQgaW4gaW1tdW5lIHJlc3BvbnNlLgoKIzA1LzExLzIwMjAgQ29tcGFyaW5nIERlIGdlbmUgbGlzdHMKSW5vcmRlciB0byBmb2xsb3cgdXAgb24gdGhlIGlkZWEgdGhhdCB0aGUgdHJlYXRtZW50IHByb2R1Y2VkIHNpbWlsYXIgZWZmZWN0cyBvbiB0aGUgbXV0YW50cyBhcyBpdCBkaWQgaW4gdGhlIHdpbGQgdHlwZSBpbSBnb2luZyB0byBjb21wYXJlIHRoZSBkaWZmZXJlbnRpYWxseSBleHByZXNzZWQgZ2VuZXMgaW4gYm90aCBncm91cHMuIEkgY2FuIHVzZSB0aGUgbGltbWEgbGlicmFyeSB0byBtYWtlIGEgdmVubiBkaWFncmFtIHNob3dpbmcgb3ZlcmxhcCBiZXR3ZWVuIHRoZSBzaWduaWZpY2FudGx5IGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcwoKYGBge3IgZmlnLndpZHRoPTh9CiNDcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggdHdvIGxpc3RzIG9mIGRpZmZlcmVudGlhbGx5IGV4cHJlc3NlZCBnZW5lcyB0byBjb21wYXJlIAp2ZW5uX2RhdGEgPSBkYXRhLmZyYW1lKE11dGFudF90cmVhdGVkX3ZzX3d0ID0gbXV0dHJlYXRlZHd0X3Jlc3VsdHMkcGFkajwwLjA1LCBXVF92c19XVF90cmVhdGVkID0gd3RfcmVzdWx0cyRwYWRqIDwgMC4wNSwgTVVUX3RyZWF0ZWRfdnNfdW50cmVhdGVkID0gbXV0cmVhdG1lbnRfcmVzdWx0cyRwYWRqIDwgMC4wNSkKCiNpbml0aWFsaXNlIHRoZSBsaW1tbWEgbGlicmFyeSBmb3IgcHJvZHVjaW5nIHRoZSB2ZW5uIGRpYWdyYW0KbGlicmFyeShsaW1tYSkKCiNQbG90IGRhdGEKdmVubkRpYWdyYW0odmVubl9kYXRhKQpgYGAKVGhlcmUgYXBwZWFycyB0byBiZSBzaWduaWZjYW50IG92ZXJsYXAgYmV0d2VlbiB0aGUgZGUgZ2VuZSBsaXN0cywgd2hpY2ggbWF5IGluZGljYXRlIHRoYXQgdGhlIHRyZWF0bWVudCBwcm9kdWNlcyBzaW1pbGFyIGFmZmVjdHMgdG8gdGhvc2Ugc2VlbiB1bmRlciBlbGV2YXRlZCBnbHVjb2NvcnRpY29pZCBzaWduYWxsaW5nLgoKIzA5LzExLzIwMjAgR2VuZSBlbnJpY2htZW50IGFuYWx5c2lzCkluIG9yZGVyIHRvIGFzc2VzcyB0aGUgYmlvbG9naWNhbCBzaWduaWZpY2FuY2Ugb2YgdGhlc2UgcmVzdWx0cyB3ZSBuZWVkIHRvIGZpZ3VyZSBvdXQgdGhlIGJpb2xvZ2ljYWwgcHJvY2Vzc2VzIHRoYXQgdGhlc2UgZ2VuZXMgYXJlIGludm9sdmVkIGluLiBUaGlzIHdpbGwgaW52b2x2ZSBnZW5lIG9udG9sb2d5IGFuYWx5c2lzLiBPdmVyIHRpbWUgZ2VuZXMgaGF2ZSBiZWVuIGFzc2lnbmVkIHRvIGNlcnRhaW4gR08gdGVybXMgKGdlbmUgb250b2xvZ3kpLiBmb3IgZXhhbXBsZSBhIGdlbmUgaW52b2x2ZWQgaW4gYW1pbm8gYWNpZCBjYXRhYm9saXNtIHdpbGwgaGF2ZSB0aGF0IGFzIGl0cyBHTyB0ZXJtLiBNdWx0aXBsZSBnZW5lcyBhcmUgYXNzaWduZWQgdG8gdGhlIHNhbWUgR08gdGVybXMsIGFuZCBnZW5lcyBjYW4gaGF2ZSBsb3RzIG9mIGRpZmZlcmVudCBHTyB0ZXJtcy4KCkluIG9yZGVyIHRvIGFzc2lnbiB0aGUgR08gdGVybXMgYW5kIHZpc3VhbGlzZSB0aGUgcmVzdWx0aW5nIGRhdGEgaSB3aWxsIGJlIHVzaW5nIHR3byBvbmxpbmUgcmVzb3VyY2VzOiBHT3JpbGxhIGFuZCByZXZpZ28uIEdPcmlsbGEgYWxsb3dzIHRoZSB1c2VyIHRvIHBhc3RlIGluIGEgc2luZ2xlIGxpc3Qgb2YgZ2VuZXMgcmFua2VkIGJ5IGFkanVzdGVkIHAgdmFsdWUsIGZyb20gbW9zdCBzaWduaWZpY2FudCB0byBsZWFzdC4gSXQgd2lsbCB0aGVuIGFzc2luZyBHTyB0ZXJtcyB0byB0aGVzZSBnZW5lcywgdGFraW5nIGludG8gYWNjb3VudCB0aGUgb3JnYW5pc20gdGhhdCB0aGV5IGJlbG9uZyB0byBhbmQgdGhlIHNpZ25pZmljYW5jZSBvZiB0aGVpciBhcHBlYXJ0YW5jZSBpbiB0aGUgbGlzdC4gQSBsaXN0IG9mIEdPIHRlcm1zIGlzIHByb2R1Y2VkIHJlbGF0aW5nIHRvIGJpb2xvZ2ljYWwgcHJvY2Vzc2VzLCBmdW5jdGlvbnMgb3IgbG9jYXRpb25zIGRlcGVuZGluZyBvbiB3aGF0IHRoZSBzdWVyIHdpc2hlcyB0byB2aWV3LgoKVGhlIGxpc3Qgb2YgR08gdGVybXMgY2FuIHRoZW4gYmUgZmVkIGludG8gcmV2aWdvLCB3aGljaCBpcyBhbiBvbmxpbmUgdG9vbCBhbGxvd2luZyBmb3IgdGhlIHZpc3VhbGlzYXRpb24gb2YgdGhpcyBsaXN0LiBJdCB0YWtlcyBpbnRvIGFjY291bnQgdGhlIHNpZ25pZmljYW5jZSBvZiBlYWNoIEdPIHRlcm0gYW5kIGFsbG93cyBmb3IgdGhlIHByb2R1Y3Rpb24gb2YgYSB0cmVlbWFwIHNob3dpbmcgZWFoIHRlcm0gaW4gZGlmZmVyZW50IHNpemVkIGJveGVzIGRlcGVuZGluZyBvbiBob3cgc29nbmlmaWNhbnRseSB0aGV5IGFwcGVhci4KClRvIHByb2R1Y2UgZWFjaCBsaXN0IGkgd2lsbCB1c2UgdGhlIGNzdiBmaWxlcyBpIGNyZWF0ZWQgZWFybGllci4gVGhlIGRhdGEgaXMgYWxyZWFkeSBvcmRlcmVkIGJ5IGFkanVzdGVkIHAgdmFsdWUsIHNvIHRoZXJlZm9yIGkganVzdCBuZWVkIHRvIHBhc3RlIHRoZSBleHRlcm5hbF9nZW5lX25hbWUgY29sdW1ucyBpbnRvIEdPcmlsbGEgdG8gZ2VuZXJhdGUgdGhlIGxpc3QuIFRoZSByZXN1bHRpbmcgbGlzdCBvZiBHTyB0ZXJtcyB3aWxsIHRoZW4gYmUgZmVkIGludG8gYW4gUiBzY3JpcHQgZ2VuZXJhdGVkIGJ5IHJldmlnbyB0byBwcm9kdWNlIHRoZSB0cmVlbWFwcwoKSSBnZW5lcmF0ZWQgZm91ciB0cmVlbWFwcyBpbiB0aGUgZm9ybSBvZiBwZGYgZmlsZXM6CgoqIE1VVFZXVC5wZGYKKiBNVVR0cmVhdFZNVVQucGRmCiogTVVUdHJlYXRWV1QucGRmCiogV1R0cmVhdFZXVC5wZGYKCk15IGFuYWx5c2lzIGlzIGZpbmlzaGVkLiBJZiBoYXZlIG1vcmUgdGltZSBvciBuZWVkIG1vcmUgcmVzdWx0cyBpIHdpbGwgaW5zZXJ0IGFsbCB1cHJlZ3VsYXRlZCBnZW5lcyBhbmQgYWxsIGRvd3JlZ3VsYXRlZCBnZW5lcyBpbnRvIEdPcmlsbGEgc2VwZXJhdGVseSBpbiBvcmRlciB0byBpZGVudGlmeSBHTyB0ZXJtcyByZWxhdGVkIHRvIHRoZW0gc3BlY2lmaWNhbGx5LCBob3dldmVyIGkgYWxyZWFkeSBoYXZlIGEgbG90IG9mIHJlc3VsdHMgc28gdGhpcyBtYXkgYmUgdG9vIG11Y2gKCgoKCgoK